From 9f2e062a33b1d15a06b912866d752e3cd21fccfe Mon Sep 17 00:00:00 2001 From: Nodari Chkuaselidze Date: Tue, 24 Sep 2024 17:51:55 +0400 Subject: [PATCH 1/6] types: update protocol types. --- lib/hd/common.js | 5 ++- lib/hd/hd.js | 16 +++++--- lib/hd/mnemonic.js | 48 +++++++++++------------ lib/hd/private.js | 69 +++++++++++++++++++-------------- lib/hd/public.js | 61 ++++++++++++++++------------- lib/primitives/abstractblock.js | 4 +- lib/primitives/claim.js | 8 +++- lib/primitives/tx.js | 4 +- lib/protocol/consensus.js | 4 ++ lib/protocol/errors.js | 20 ++++++---- lib/protocol/network.js | 28 ++++++------- lib/protocol/networks.js | 11 +++--- lib/protocol/policy.js | 11 ++++-- lib/types.js | 8 ++-- lib/utils/binary.js | 8 +++- 15 files changed, 181 insertions(+), 124 deletions(-) diff --git a/lib/hd/common.js b/lib/hd/common.js index 507f6608c..256dd3259 100644 --- a/lib/hd/common.js +++ b/lib/hd/common.js @@ -10,6 +10,9 @@ const assert = require('bsert'); const LRU = require('blru'); const common = exports; +/** @typedef {import('./private')} HDPrivateKey */ +/** @typedef {import('./public')} HDPublicKey */ + /** * Index at which hardening begins. * @const {Number} @@ -36,7 +39,7 @@ common.MAX_ENTROPY = 512; /** * LRU cache to avoid deriving keys twice. - * @type {LRU} + * @type {LRU} */ common.cache = new LRU(500); diff --git a/lib/hd/hd.js b/lib/hd/hd.js index 0ca02ec3c..264233738 100644 --- a/lib/hd/hd.js +++ b/lib/hd/hd.js @@ -13,6 +13,10 @@ const HDPrivateKey = require('./private'); const HDPublicKey = require('./public'); const wordlist = require('./wordlist'); +/** @typedef {import('../protocol/network')} Network */ +/** @typedef {import('../types').Base58String} Base58String */ +/** @typedef {import('../types').NetworkType} NetworkType */ + /** * @exports hd */ @@ -22,7 +26,7 @@ const HD = exports; /** * Instantiate an HD key (public or private) from an base58 string. * @param {Base58String} xkey - * @param {Network?} network + * @param {(Network|NetworkType)?} [network] * @returns {HDPrivateKey|HDPublicKey} */ @@ -58,7 +62,7 @@ HD.fromSeed = function fromSeed(options) { /** * Instantiate an hd private key from a mnemonic. * @param {Mnemonic} mnemonic - * @param {String?} bip39Passphrase + * @param {String?} [bip39Passphrase] * @returns {HDPrivateKey} */ @@ -82,7 +86,7 @@ HD.fromJSON = function fromJSON(json, network) { /** * Instantiate an HD key from serialized data. * @param {Buffer} data - * @param {Network?} network + * @param {(Network|NetworkType)?} [network] * @returns {HDPrivateKey|HDPublicKey} */ @@ -121,7 +125,7 @@ HD.from = function from(options, network) { /** * Test whether an object is in the form of a base58 hd key. * @param {String} data - * @param {Network?} network + * @param {(Network|NetworkType)?} [network] * @returns {Boolean} */ @@ -133,8 +137,8 @@ HD.isBase58 = function isBase58(data, network) { /** * Test whether an object is in the form of a serialized hd key. * @param {Buffer} data - * @param {Network?} network - * @returns {NetworkType} + * @param {(Network|NetworkType)?} [network] + * @returns {Boolean} */ HD.isRaw = function isRaw(data, network) { diff --git a/lib/hd/mnemonic.js b/lib/hd/mnemonic.js index 819ff2592..20e9f0ea4 100644 --- a/lib/hd/mnemonic.js +++ b/lib/hd/mnemonic.js @@ -23,6 +23,14 @@ const nfkd = require('./nfkd'); const wordlistCache = Object.create(null); +/** + * @typedef {Object} MnemonicOptions + * @property {Number?} [bits] + * @property {Buffer?} [entropy] + * @property {String?} [phrase] + * @property {String?} [language] + */ + /** * HD Mnemonic * @alias module:hd.Mnemonic @@ -32,15 +40,7 @@ class Mnemonic extends bio.Struct { /** * Create a mnemonic. * @constructor - * @param {Object} options - * @param {Number?} options.bit - Bits of entropy (Must - * be a multiple of 8) (default=256). - * @param {Buffer?} options.entropy - Entropy bytes. Will - * be generated with `options.bits` bits of entropy - * if not present. - * @param {String?} options.phrase - Mnemonic phrase (will - * be generated if not present). - * @param {String?} options.language - Language. + * @param {String|MnemonicOptions} [options] */ constructor(options) { @@ -56,8 +56,7 @@ class Mnemonic extends bio.Struct { /** * Inject properties from options object. - * @private - * @param {Object} options + * @param {String|MnemonicOptions} options */ fromOptions(options) { @@ -109,7 +108,7 @@ class Mnemonic extends bio.Struct { /** * Generate the seed. - * @param {String?} passphrase + * @param {String?} [passphrase] * @returns {Buffer} pbkdf2 seed. */ @@ -169,7 +168,9 @@ class Mnemonic extends bio.Struct { // 11 bit indexes from the entropy. const list = Mnemonic.getWordlist(this.language); - let phrase = []; + /** @type {String[]} */ + const words = []; + for (let i = 0; i < wbits / 11; i++) { let index = 0; for (let j = 0; j < 11; j++) { @@ -179,14 +180,15 @@ class Mnemonic extends bio.Struct { index <<= 1; index |= (data[oct] >>> (7 - bit)) & 1; } - phrase.push(list.words[index]); + words.push(list.words[index]); } + let phrase; // Japanese likes double-width spaces. if (this.language === 'japanese') - phrase = phrase.join('\u3000'); + phrase = words.join('\u3000'); else - phrase = phrase.join(' '); + phrase = words.join(' '); this.phrase = phrase; @@ -195,7 +197,6 @@ class Mnemonic extends bio.Struct { /** * Inject properties from phrase. - * @private * @param {String} phrase */ @@ -284,7 +285,7 @@ class Mnemonic extends bio.Struct { * Inject properties from entropy. * @private * @param {Buffer} entropy - * @param {String?} lang + * @param {String?} [lang] */ fromEntropy(entropy, lang) { @@ -334,7 +335,7 @@ class Mnemonic extends bio.Struct { /** * Retrieve the wordlist for a language. * @param {String} lang - * @returns {Object} + * @returns {WordList} */ static getWordlist(lang) { @@ -367,7 +368,6 @@ class Mnemonic extends bio.Struct { /** * Inject properties from json object. - * @private * @param {Object} json */ @@ -404,7 +404,8 @@ class Mnemonic extends bio.Struct { /** * Write the mnemonic to a buffer writer. - * @params {BufferWriter} bw + * @param {bio.BufferWriter} bw + * @returns {bio.BufferWriter} */ write(bw) { @@ -421,8 +422,7 @@ class Mnemonic extends bio.Struct { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -498,7 +498,7 @@ class WordList { * Create word list. * @constructor * @ignore - * @param {Array} words + * @param {String[]} words */ constructor(words) { diff --git a/lib/hd/private.js b/lib/hd/private.js index 17dcaafa4..29a9d3745 100644 --- a/lib/hd/private.js +++ b/lib/hd/private.js @@ -21,12 +21,24 @@ const common = require('./common'); const Mnemonic = require('./mnemonic'); const HDPublicKey = require('./public'); +/** @typedef {import('../types').Base58String} Base58String */ +/** @typedef {import('../types').NetworkType} NetworkType */ + /* * Constants */ const SEED_SALT = Buffer.from('Bitcoin seed', 'ascii'); +/** + * @typedef {Object} HDPrivateKeyOptions + * @property {Number} depth + * @property {Number} parentFingerPrint + * @property {Number} childIndex + * @property {Buffer} chainCode + * @property {Buffer} privateKey + */ + /** * HDPrivateKey * @alias module:hd.PrivateKey @@ -41,12 +53,7 @@ class HDPrivateKey extends bio.Struct { /** * Create an hd private key. * @constructor - * @param {Object|String} options - * @param {Number?} options.depth - * @param {Number?} options.parentFingerPrint - * @param {Number?} options.childIndex - * @param {Buffer?} options.chainCode - * @param {Buffer?} options.privateKey + * @param {HDPrivateKeyOptions} [options] */ constructor(options) { @@ -69,8 +76,7 @@ class HDPrivateKey extends bio.Struct { /** * Inject properties from options object. - * @private - * @param {Object} options + * @param {HDPrivateKeyOptions} options */ fromOptions(options) { @@ -114,6 +120,7 @@ class HDPrivateKey extends bio.Struct { /** * Get cached base58 xprivkey. + * @param {(NetworkType|Network)?} [network] * @returns {Base58String} */ @@ -123,6 +130,7 @@ class HDPrivateKey extends bio.Struct { /** * Get cached base58 xpubkey. + * @param {(NetworkType|Network)?} [network] * @returns {Base58String} */ @@ -156,7 +164,7 @@ class HDPrivateKey extends bio.Struct { /** * Derive a child key. * @param {Number} index - Derivation index. - * @param {Boolean?} hardened - Whether the derivation should be hardened. + * @param {Boolean?} [hardened] - Whether the derivation should be hardened. * @returns {HDPrivateKey} */ @@ -175,7 +183,10 @@ class HDPrivateKey extends bio.Struct { } const id = this.getID(index); - const cache = common.cache.get(id); + + /** @type {HDPrivateKey} */ + // @ts-ignore + const cache = common.cache.get(id); if (cache) return cache; @@ -209,6 +220,8 @@ class HDPrivateKey extends bio.Struct { this.fingerPrint = fp.readUInt32BE(0, true); } + /** @type {HDPrivateKey} */ + // @ts-ignore const child = new this.constructor(); child.depth = this.depth + 1; child.parentFingerPrint = this.fingerPrint; @@ -275,7 +288,7 @@ class HDPrivateKey extends bio.Struct { /** * Test whether an object is in the form of a base58 xprivkey. * @param {String} data - * @param {Network?} network + * @param {(Network|NetworkType)?} [network] * @returns {Boolean} */ @@ -299,7 +312,7 @@ class HDPrivateKey extends bio.Struct { /** * Test whether a buffer has a valid network prefix. * @param {Buffer} data - * @param {Network?} network + * @param {(Network|NetworkType)?} [network] * @returns {Boolean} */ @@ -310,7 +323,7 @@ class HDPrivateKey extends bio.Struct { if (data.length < 4) return false; - const version = data.readUInt32BE(0, true); + const version = data.readUInt32BE(0); try { Network.fromPrivate(version, network); @@ -345,6 +358,7 @@ class HDPrivateKey extends bio.Struct { derivePath(path) { const indexes = common.parsePath(path, true); + /** @type {HDPrivateKey} */ let key = this; for (const index of indexes) @@ -355,7 +369,7 @@ class HDPrivateKey extends bio.Struct { /** * Compare a key against an object. - * @param {Object} obj + * @param {HDPrivateKey} obj * @returns {Boolean} */ @@ -371,8 +385,8 @@ class HDPrivateKey extends bio.Struct { /** * Compare a key against an object. - * @param {Object} obj - * @returns {Boolean} + * @param {HDPrivateKey} key + * @returns {Number} */ compare(key) { @@ -450,9 +464,8 @@ class HDPrivateKey extends bio.Struct { /** * Inject properties from a mnemonic. - * @private * @param {Mnemonic} mnemonic - * @param {String?} passphrase + * @param {String?} [passphrase] */ fromMnemonic(mnemonic, passphrase) { @@ -463,7 +476,7 @@ class HDPrivateKey extends bio.Struct { /** * Instantiate an hd private key from a mnemonic. * @param {Mnemonic} mnemonic - * @param {String?} passphrase + * @param {String?} [passphrase] * @returns {HDPrivateKey} */ @@ -473,8 +486,7 @@ class HDPrivateKey extends bio.Struct { /** * Inject properties from a mnemonic. - * @private - * @param {String} mnemonic + * @param {String} phrase */ fromPhrase(phrase) { @@ -538,7 +550,7 @@ class HDPrivateKey extends bio.Struct { * Inject properties from base58 key. * @private * @param {Base58String} xkey - * @param {Network?} network + * @param {(Network|NetworkType)?} [network] */ fromBase58(xkey, network) { @@ -548,9 +560,8 @@ class HDPrivateKey extends bio.Struct { /** * Inject properties from serialized data. - * @private - * @param {BufferReader} br - * @param {(Network|NetworkType)?} network + * @param {bio.BufferReader} br + * @param {(Network|NetworkType)?} [network] */ read(br, network) { @@ -592,7 +603,7 @@ class HDPrivateKey extends bio.Struct { /** * Write the key to a buffer writer. - * @param {BufferWriter} bw + * @param {bio.BufferWriter} bw * @param {(Network|NetworkType)?} network */ @@ -614,7 +625,7 @@ class HDPrivateKey extends bio.Struct { /** * Instantiate an HD private key from a base58 string. * @param {Base58String} xkey - * @param {Network?} network + * @param {(Network|NetworkType)?} [network] * @returns {HDPrivateKey} */ @@ -624,6 +635,7 @@ class HDPrivateKey extends bio.Struct { /** * Convert key to a more json-friendly object. + * @param {(Network|NetworkType)?} [network] * @returns {Object} */ @@ -635,9 +647,8 @@ class HDPrivateKey extends bio.Struct { /** * Inject properties from json object. - * @private * @param {Object} json - * @param {Network?} network + * @param {(Network|NetworkType)?} [network] */ fromJSON(json, network) { diff --git a/lib/hd/public.js b/lib/hd/public.js index 032a0e4fc..1d68d5320 100644 --- a/lib/hd/public.js +++ b/lib/hd/public.js @@ -18,6 +18,19 @@ const Network = require('../protocol/network'); const consensus = require('../protocol/consensus'); const common = require('./common'); +/** @typedef {import('../types').Base58String} Base58String */ +/** @typedef {import('../types').NetworkType} NetworkType */ +/** @typedef {String} HDPublicKeyID */ + +/** + * @typedef HDPublicKeyOptions + * @property {Number} depth + * @property {Number} parentFingerPrint + * @property {Number} childIndex + * @property {Buffer} chainCode + * @property {Buffer} publicKey + */ + /** * HDPublicKey * @alias module:hd.PublicKey @@ -32,13 +45,7 @@ class HDPublicKey extends bio.Struct { /** * Create an HD public key. * @constructor - * @param {Object|Base58String} options - * @param {Base58String?} options.xkey - Serialized base58 key. - * @param {Number?} options.depth - * @param {Number?} options.parentFingerPrint - * @param {Number?} options.childIndex - * @param {Buffer?} options.chainCode - * @param {Buffer?} options.publicKey + * @param {HDPublicKeyOptions} [options] */ constructor(options) { @@ -58,8 +65,7 @@ class HDPublicKey extends bio.Struct { /** * Inject properties from options object. - * @private - * @param {Object} options + * @param {HDPublicKeyOptions} options */ fromOptions(options) { @@ -90,6 +96,7 @@ class HDPublicKey extends bio.Struct { /** * Get cached base58 xprivkey (always null here). + * @param {(NetworkType|Network)?} [network] * @returns {null} */ @@ -124,9 +131,9 @@ class HDPublicKey extends bio.Struct { /** * Derive a child key. * @param {Number} index - Derivation index. - * @param {Boolean?} hardened - Whether the derivation + * @param {Boolean?} [hardened] - Whether the derivation * should be hardened (throws if true). - * @returns {HDPrivateKey} + * @returns {HDPublicKey} * @throws on `hardened` */ @@ -143,6 +150,8 @@ class HDPublicKey extends bio.Struct { throw new Error('Depth too high.'); const id = this.getID(index); + /** @type {HDPublicKey} */ + // @ts-ignore const cache = common.cache.get(id); if (cache) @@ -171,6 +180,8 @@ class HDPublicKey extends bio.Struct { this.fingerPrint = fp.readUInt32BE(0, true); } + /** @type {HDPublicKey} */ + // @ts-ignore const child = new this.constructor(); child.depth = this.depth + 1; child.parentFingerPrint = this.fingerPrint; @@ -236,7 +247,6 @@ class HDPublicKey extends bio.Struct { /** * Test whether a string is a valid path. * @param {String} path - * @param {Boolean?} hardened * @returns {Boolean} */ @@ -260,6 +270,7 @@ class HDPublicKey extends bio.Struct { derivePath(path) { const indexes = common.parsePath(path, false); + /** @type {HDPublicKey} */ let key = this; for (const index of indexes) @@ -270,7 +281,7 @@ class HDPublicKey extends bio.Struct { /** * Compare a key against an object. - * @param {Object} obj + * @param {HDPublicKey} obj * @returns {Boolean} */ @@ -286,8 +297,8 @@ class HDPublicKey extends bio.Struct { /** * Compare a key against an object. - * @param {Object} obj - * @returns {Boolean} + * @param {HDPublicKey} key + * @returns {Number} */ compare(key) { @@ -323,6 +334,7 @@ class HDPublicKey extends bio.Struct { /** * Convert key to a more json-friendly object. + * @param {(Network|NetworkType)?} [network] * @returns {Object} */ @@ -334,9 +346,8 @@ class HDPublicKey extends bio.Struct { /** * Inject properties from json object. - * @private * @param {Object} json - * @param {Network?} network + * @param {(Network|NetworkType)?} [network] */ fromJSON(json, network) { @@ -372,8 +383,8 @@ class HDPublicKey extends bio.Struct { /** * Test whether a buffer has a valid network prefix. * @param {Buffer} data - * @param {(Network|NetworkType)?} network - * @returns {NetworkType} + * @param {(Network|NetworkType)?} [network] + * @returns {Boolean} */ static isRaw(data, network) { @@ -383,7 +394,7 @@ class HDPublicKey extends bio.Struct { if (data.length < 4) return false; - const version = data.readUInt32BE(0, true); + const version = data.readUInt32BE(0); try { Network.fromPublic(version, network); @@ -395,9 +406,8 @@ class HDPublicKey extends bio.Struct { /** * Inject properties from a base58 key. - * @private * @param {Base58String} xkey - * @param {Network?} network + * @param {(Network|NetworkType)?} [network] */ fromBase58(xkey, network) { @@ -407,8 +417,7 @@ class HDPublicKey extends bio.Struct { /** * Inject properties from serialized data. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br * @param {(Network|NetworkType)?} network */ @@ -440,7 +449,7 @@ class HDPublicKey extends bio.Struct { /** * Write the key to a buffer writer. - * @param {BufferWriter} bw + * @param {bio.BufferWriter} bw * @param {(Network|NetworkType)?} network */ @@ -470,7 +479,7 @@ class HDPublicKey extends bio.Struct { /** * Instantiate an HD public key from a base58 string. * @param {Base58String} xkey - * @param {Network?} network + * @param {(Network|NetworkType)?} [network] * @returns {HDPublicKey} */ diff --git a/lib/primitives/abstractblock.js b/lib/primitives/abstractblock.js index d1395f7f1..edbc476b5 100644 --- a/lib/primitives/abstractblock.js +++ b/lib/primitives/abstractblock.js @@ -14,6 +14,8 @@ const InvItem = require('./invitem'); const consensus = require('../protocol/consensus'); const util = require('../utils/util'); +/** @typedef {import('../types').Hash} Hash */ + /** * Abstract Block * The class which all block-like objects inherit from. @@ -152,7 +154,7 @@ class AbstractBlock extends bio.Struct { /** * Hash the block header. - * @returns {Hash} hash + * @returns {Hash} */ hash() { diff --git a/lib/primitives/claim.js b/lib/primitives/claim.js index 32b6b8858..470212648 100644 --- a/lib/primitives/claim.js +++ b/lib/primitives/claim.js @@ -19,6 +19,8 @@ const Input = require('./input'); const Output = require('./output'); const {OwnershipProof} = Ownership; +/** @typedef {import('../types').Hash} Hash */ + /* * Constants */ @@ -27,7 +29,7 @@ const EMPTY = Buffer.alloc(0); /** * Claim - * @extends {bufio.Struct} + * @extends {bio.Struct} */ class Claim extends bio.Struct { @@ -46,6 +48,10 @@ class Claim extends bio.Struct { return this; } + /** + * @returns {Hash} + */ + hash() { if (!this._hash) this._hash = blake2b.digest(this.blob); diff --git a/lib/primitives/tx.js b/lib/primitives/tx.js index c1bc6b6d8..6a203f7dc 100644 --- a/lib/primitives/tx.js +++ b/lib/primitives/tx.js @@ -28,6 +28,8 @@ const AirdropProof = require('../primitives/airdropproof'); const {encoding} = bio; const {hashType} = Script; +/** @typedef {import('../types').Hash} Hash */ + /** * TX * A static transaction object. @@ -149,7 +151,7 @@ class TX extends bio.Struct { /** * Hash the transaction with the non-witness serialization. - * @returns {Hash} hash + * @returns {Hash} */ hash() { diff --git a/lib/protocol/consensus.js b/lib/protocol/consensus.js index 39b5e85fe..808129653 100644 --- a/lib/protocol/consensus.js +++ b/lib/protocol/consensus.js @@ -13,6 +13,9 @@ const assert = require('bsert'); const BN = require('bcrypto/lib/bn.js'); +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').Amount} Amount */ + /** * Coin exponent. * @const {Number} @@ -477,6 +480,7 @@ exports.verifyPOW = function verifyPOW(hash, bits) { /** * Calculate block subsidy. * @param {Number} height - Reward era by height. + * @param {Number} interval - halving interval. * @returns {Amount} */ diff --git a/lib/protocol/errors.js b/lib/protocol/errors.js index e0ddbd266..135bcee8e 100644 --- a/lib/protocol/errors.js +++ b/lib/protocol/errors.js @@ -1,3 +1,4 @@ +// @ts-check /*! * errors.js - error objects for hsd * Copyright (c) 2017-2018, Christopher Jeffrey (MIT License). @@ -12,6 +13,11 @@ const assert = require('bsert'); +/** @typedef {import('../primitives/block')} Block */ +/** @typedef {import('../primitives/tx')} TX */ +/** @typedef {import('../primitives/claim')} Claim */ +/** @typedef {import('../types').Hash} Hash */ + /** * Verify Error * An error thrown during verification. Can be either @@ -19,24 +25,24 @@ const assert = require('bsert'); * block verification error. Ultimately used to send * `reject` packets to peers. * @extends Error - * @param {Block|TX} msg - * @param {String} code - Reject packet code. - * @param {String} reason - Reject packet reason. - * @param {Number} score - Ban score increase + * @property {Block|TX|Claim} msg + * @property {String} code - Reject packet code. + * @property {String} reason - Reject packet reason. + * @property {Number} score - Ban score increase * (can be -1 for no reject packet). - * @param {Boolean} malleated + * @property {Boolean} malleated */ class VerifyError extends Error { /** * Create a verify error. * @constructor - * @param {Block|TX} msg + * @param {Block|TX|Claim} msg * @param {String} code - Reject packet code. * @param {String} reason - Reject packet reason. * @param {Number} score - Ban score increase * (can be -1 for no reject packet). - * @param {Boolean} malleated + * @param {Boolean} [malleated=false] */ constructor(msg, code, reason, score, malleated) { diff --git a/lib/protocol/network.js b/lib/protocol/network.js index b286033ee..307a8e8ef 100644 --- a/lib/protocol/network.js +++ b/lib/protocol/network.js @@ -11,6 +11,8 @@ const binary = require('../utils/binary'); const networks = require('./networks'); const TimeData = require('./timedata'); +/** @typedef {import('../types').NetworkType} NetworkType */ + /** * Network * Represents a network. @@ -71,8 +73,6 @@ class Network { /** * Get a deployment by bit index. - * @param {Number} bit - * @returns {Object} */ init() { @@ -217,7 +217,7 @@ class Network { * @private * @param {Object} value * @param {Function} compare - * @param {Network|null} network + * @param {(NetworkType|Network)?} network * @param {String} name * @returns {Network} */ @@ -242,7 +242,7 @@ class Network { /** * Get a network by its magic number. * @param {Number} value - * @param {Network?} network + * @param {(Network|NetworkType)?} [network] * @returns {Network} */ @@ -252,8 +252,8 @@ class Network { /** * Get a network by its WIF prefix. - * @param {Number} value - * @param {Network?} network + * @param {Number} prefix + * @param {(Network|NetworkType)?} [network] * @returns {Network} */ @@ -263,8 +263,8 @@ class Network { /** * Get a network by its xpubkey prefix. - * @param {Number} value - * @param {Network?} network + * @param {Number} prefix + * @param {(Network|NetworkType)?} [network] * @returns {Network} */ @@ -274,8 +274,8 @@ class Network { /** * Get a network by its xprivkey prefix. - * @param {Number} value - * @param {Network?} network + * @param {Number} prefix + * @param {(Network|NetworkType)?} [network] * @returns {Network} */ @@ -286,7 +286,7 @@ class Network { /** * Get a network by its xpubkey base58 prefix. * @param {String} prefix - * @param {Network?} network + * @param {(Network|NetworkType)?} [network] * @returns {Network} */ @@ -297,7 +297,7 @@ class Network { /** * Get a network by its xprivkey base58 prefix. * @param {String} prefix - * @param {Network?} network + * @param {(Network|NetworkType)?} [network] * @returns {Network} */ @@ -308,7 +308,7 @@ class Network { /** * Get a network by its bech32 address prefix. * @param {String} hrp - * @param {Network?} network + * @param {(Network|NetworkType)?} [network] * @returns {Network} */ @@ -366,13 +366,13 @@ Network.type = null; Network.main = null; Network.testnet = null; Network.regtest = null; -Network.segnet4 = null; Network.simnet = null; /* * Set initial network. */ +// @ts-ignore Network.set(process.env.HSD_NETWORK || 'main'); /* diff --git a/lib/protocol/networks.js b/lib/protocol/networks.js index efef78df9..bfbbc30fc 100644 --- a/lib/protocol/networks.js +++ b/lib/protocol/networks.js @@ -12,6 +12,8 @@ * @module protocol/networks */ +/** @typedef {import('../types').NetworkType} NetworkType */ + const BN = require('bcrypto/lib/bn.js'); const genesis = require('./genesis'); const network = exports; @@ -19,7 +21,8 @@ const network = exports; /** * Network type list. * @memberof module:protocol/networks - * @const {String[]} + * @const {NetworkType[]} + * @type {NetworkType[]} * @default */ @@ -260,8 +263,6 @@ main.txStart = 14 * main.pow.blocksPerDay; /** * Name-related constants. - * @enum {Number} - * @default */ main.names = { @@ -386,8 +387,6 @@ main.names = { /** * Block constants. - * @enum {Number} - * @default */ main.block = { @@ -501,7 +500,7 @@ main.deploys = [ /** * Key prefixes. - * @enum {Number} + * @enum {Number|String} * @default */ diff --git a/lib/protocol/policy.js b/lib/protocol/policy.js index 60cafd6c4..9e688ebc7 100644 --- a/lib/protocol/policy.js +++ b/lib/protocol/policy.js @@ -13,6 +13,9 @@ const assert = require('bsert'); const consensus = require('./consensus'); +/** @typedef {import('../types').Amount} Amount */ +/** @typedef {import('../types').Rate} Rate */ + /** * Maximum transaction version (policy). * @const {Number} @@ -177,8 +180,8 @@ exports.BLOCK_PRIORITY_THRESHOLD = exports.FREE_THRESHOLD; /** * Calculate minimum fee based on rate and size. - * @param {Number?} size - * @param {Rate?} rate - Rate of dollarydoo per kB. + * @param {Number} size + * @param {Rate?} [rate] - Rate of dollarydoo per kB. * @returns {Amount} fee */ @@ -204,8 +207,8 @@ exports.getMinFee = function getMinFee(size, rate) { * Calculate the minimum fee in order for the transaction * to be relayable, but _round to the nearest kilobyte * when taking into account size. - * @param {Number?} size - * @param {Rate?} rate - Rate of dollarydoo per kB. + * @param {Number} size + * @param {Rate?} [rate] - Rate of dollarydoo per kB. * @returns {Amount} fee */ diff --git a/lib/types.js b/lib/types.js index f68fb6c3d..7af05aa3c 100644 --- a/lib/types.js +++ b/lib/types.js @@ -104,9 +104,9 @@ */ /** - * One of `main`, `testnet`, `regtest`, `segnet3`, `segnet4`. - * @typedef {String} NetworkType - * @see {module:network.types} + * One of `main`, `testnet`, `regtest`, `simnet`. + * @typedef {'main'|'testnet'|'regtest'|'simnet'} NetworkType + * @see {network.types} * @global */ @@ -115,3 +115,5 @@ * @typedef {String} AmountUnitType * @global */ + +module.exports = {}; diff --git a/lib/utils/binary.js b/lib/utils/binary.js index ad3b19abd..8e4cafcf7 100644 --- a/lib/utils/binary.js +++ b/lib/utils/binary.js @@ -11,7 +11,7 @@ * @param {Array} items * @param {Object} key * @param {Function} compare - * @param {Boolean?} insert + * @param {Boolean} [insert=false] * @returns {Number} Index. */ @@ -43,6 +43,7 @@ exports.search = function search(items, key, compare, insert) { * @param {Array} items * @param {Object} item * @param {Function} compare + * @param {Boolean} [uniq=false] * @returns {Number} index */ @@ -87,6 +88,11 @@ exports.remove = function remove(items, item, compare) { * Helpers */ +/** + * @param {Array} list + * @param {Number} i + */ + function splice(list, i) { if (i === 0) { list.shift(); From ecac38777760f18bf6273446d26db502898b1e5e Mon Sep 17 00:00:00 2001 From: Nodari Chkuaselidze Date: Tue, 24 Sep 2024 23:20:07 +0400 Subject: [PATCH 2/6] types: update misc types in utils, ui and address. --- lib/primitives/address.js | 59 ++++++++++++++++++++++----------------- lib/types.js | 2 +- lib/ui/amount.js | 36 +++++++++++------------- lib/ui/uri.js | 29 ++++++++++++++----- lib/utils/fixed.js | 16 +++++------ lib/utils/hashlist.js | 9 ++++++ lib/utils/util.js | 28 ++++++++++--------- 7 files changed, 104 insertions(+), 75 deletions(-) diff --git a/lib/primitives/address.js b/lib/primitives/address.js index f555a8d80..2bb65be04 100644 --- a/lib/primitives/address.js +++ b/lib/primitives/address.js @@ -14,12 +14,23 @@ const sha3 = require('bcrypto/lib/sha3'); const Network = require('../protocol/network'); const consensus = require('../protocol/consensus'); +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').NetworkType} NetworkType */ +/** @typedef {import('../script/script')} Script */ +/** @typedef {import('../script/witness')} Witness */ + /* * Constants */ const ZERO_HASH160 = Buffer.alloc(20, 0x00); +/** + * @typedef {Object} AddressOptions + * @property {Hash} hash + * @property {Number} version + */ + /** * Address * Represents an address. @@ -32,7 +43,8 @@ class Address extends bio.Struct { /** * Create an address. * @constructor - * @param {Object?} options + * @param {AddressOptions|String} [options] + * @param {(NetworkType|Network)?} [network] */ constructor(options, network) { @@ -47,8 +59,8 @@ class Address extends bio.Struct { /** * Inject properties from options object. - * @private - * @param {Object} options + * @param {AddressOptions|String} options + * @param {(NetworkType|Network)?} [network] */ fromOptions(options, network) { @@ -136,7 +148,7 @@ class Address extends bio.Struct { /** * Compare against another address. * @param {Address} addr - * @returns {Boolean} + * @returns {Number} */ compare(addr) { @@ -153,7 +165,7 @@ class Address extends bio.Struct { /** * Inject properties from another address. * @param {Address} addr - * @returns {Boolean} + * @returns {this} */ inject(addr) { @@ -164,16 +176,17 @@ class Address extends bio.Struct { /** * Clone address. - * @returns {Address} + * @returns {this} */ clone() { + // @ts-ignore return new this.constructor().inject(this); } /** * Compile the address object to a bech32 address. - * @param {(NetworkType|Network)?} network + * @param {(NetworkType|Network)?} [network] * @returns {String} * @throws Error on bad hash/prefix. */ @@ -216,9 +229,8 @@ class Address extends bio.Struct { /** * Inject properties from bech32 address. - * @private * @param {String} data - * @param {Network?} network + * @param {(NetworkType|Network)?} [network] * @throws Parse error */ @@ -234,8 +246,8 @@ class Address extends bio.Struct { /** * Inject properties from witness. - * @private * @param {Witness} witness + * @returns {Address|null} */ fromWitness(witness) { @@ -260,9 +272,8 @@ class Address extends bio.Struct { /** * Inject properties from a hash. - * @private - * @param {Buffer|Hash} hash - * @param {Number} [version=-1] + * @param {Hash} hash + * @param {Number} [version=0] * @throws on bad hash size */ @@ -289,7 +300,6 @@ class Address extends bio.Struct { /** * Inject properties from witness pubkeyhash. - * @private * @param {Buffer} hash * @returns {Address} */ @@ -301,7 +311,6 @@ class Address extends bio.Struct { /** * Inject properties from witness scripthash. - * @private * @param {Buffer} hash * @returns {Address} */ @@ -313,7 +322,6 @@ class Address extends bio.Struct { /** * Inject properties from witness program. - * @private * @param {Number} version * @param {Buffer} hash * @returns {Address} @@ -404,8 +412,8 @@ class Address extends bio.Struct { /** * Write address to buffer writer. - * @param {BufferWriter} bw - * @returns {BufferWriter} + * @param {bio.BufferWriter} bw + * @returns {bio.BufferWriter} */ write(bw) { @@ -417,8 +425,8 @@ class Address extends bio.Struct { /** * Read address from buffer reader. - * @param {BufferReader} br - * @returns {Address} + * @param {bio.BufferReader} br + * @returns {this} */ read(br) { @@ -435,7 +443,7 @@ class Address extends bio.Struct { /** * Inspect the Address. - * @returns {Object} + * @returns {String} */ format() { @@ -469,7 +477,7 @@ class Address extends bio.Struct { * Create an Address from a witness. * Attempt to extract address * properties from a witness. - * @param {Witness} + * @param {Witness} witness * @returns {Address|null} */ @@ -480,7 +488,7 @@ class Address extends bio.Struct { /** * Create a naked address from hash/version. * @param {Hash} hash - * @param {Number} [version=-1] + * @param {Number} [version=0] * @returns {Address} * @throws on bad hash size */ @@ -532,12 +540,11 @@ class Address extends bio.Struct { /** * Get the hash of a base58 address or address-related object. - * @param {String|Address|Hash} data - * @param {Network?} network + * @param {Address|Hash} data * @returns {Hash} */ - static getHash(data, network) { + static getHash(data) { if (!data) throw new Error('Object is not an address.'); diff --git a/lib/types.js b/lib/types.js index 7af05aa3c..9f4458928 100644 --- a/lib/types.js +++ b/lib/types.js @@ -112,7 +112,7 @@ /** * One of `doo`, `uhns`, `mhns`, `hns`, `handshake`. - * @typedef {String} AmountUnitType + * @typedef {'doo'|'uhns'|'mhns'|'hns'|'handshake'} AmountUnitType * @global */ diff --git a/lib/ui/amount.js b/lib/ui/amount.js index 15ceea9cb..36b486a33 100644 --- a/lib/ui/amount.js +++ b/lib/ui/amount.js @@ -11,6 +11,9 @@ const fixed = require('../utils/fixed'); const {EXP} = require('../protocol/consensus'); const pkg = require('../pkg'); +/** @typedef {import('../types').AmountUnitType} AmountUnitType */ +/** @typedef {import('../types').Amount} AmountValue */ + /** * Amount * Represents a currency amount (base unit internally). @@ -22,7 +25,7 @@ class Amount { /** * Create an amount. * @constructor - * @param {(String|Number)?} value + * @param {(String|Number)?} [value] * @param {AmountUnitType} [unit=doo] */ @@ -35,7 +38,6 @@ class Amount { /** * Inject properties from options. - * @private * @param {String|Number} value * @param {AmountUnitType} [unit=doo] * @returns {Amount} @@ -53,7 +55,7 @@ class Amount { /** * Get base unit value. - * @returns {Amount} + * @returns {AmountValue} */ toValue() { @@ -63,7 +65,7 @@ class Amount { /** * Get base unit string or value. * @param {Boolean} [num=false] - Return a number. - * @returns {String|Amount} + * @returns {String|AmountValue} */ toBase(num) { @@ -76,7 +78,7 @@ class Amount { /** * Get mhns string or value. * @param {Boolean} [num=false] - Return a number. - * @returns {String|Amount} + * @returns {String|AmountValue} */ toMilli(num) { @@ -86,7 +88,7 @@ class Amount { /** * Get currency string or value. * @param {Boolean} [num=false] - Return a number. - * @returns {String|Amount} + * @returns {String|AmountValue} */ toCoins(num) { @@ -97,7 +99,7 @@ class Amount { * Get unit string or value. * @param {AmountUnitType} unit * @param {Boolean} [num=false] - Return a number. - * @returns {String|Amount} + * @returns {String|AmountValue} * @throws on incorrect unit type. */ @@ -117,7 +119,7 @@ class Amount { /** * Convert amount to currency string. - * @returns {String} + * @returns {String|AmountValue} */ toString() { @@ -126,8 +128,7 @@ class Amount { /** * Inject properties from value. - * @private - * @param {Amount} value + * @param {AmountValue} value * @returns {Amount} */ @@ -140,7 +141,6 @@ class Amount { /** * Inject properties from base unit. - * @private * @param {Number|String} value * @returns {Amount} */ @@ -152,7 +152,6 @@ class Amount { /** * Inject properties from mhns. - * @private * @param {Number|String} value * @returns {Amount} */ @@ -164,7 +163,6 @@ class Amount { /** * Inject properties from value. - * @private * @param {Number|String} value * @returns {Amount} */ @@ -176,7 +174,6 @@ class Amount { /** * Inject properties from unit. - * @private * @param {AmountUnitType} unit * @param {Number|String} value * @returns {Amount} @@ -210,8 +207,7 @@ class Amount { /** * Instantiate amount from value. - * @private - * @param {Amount} value + * @param {AmountValue} value * @returns {Amount} */ @@ -273,7 +269,7 @@ class Amount { * Safely convert base unit to a currency string. * This function explicitly avoids any * floating point arithmetic. - * @param {Amount} value - Base unit. + * @param {AmountValue} value - Base unit. * @param {Boolean} [num=false] - Return a number. * @returns {String|Number} Currency string. */ @@ -288,7 +284,7 @@ class Amount { /** * Safely convert a currency string to base unit. * @param {String} str - * @returns {Amount} Base unit. + * @returns {AmountValue} Base unit. * @throws on parse error */ @@ -301,7 +297,7 @@ class Amount { /** * Safely convert base unit to a currency string. - * @param {Amount} value + * @param {AmountValue} value * @param {Number} exp - Exponent. * @param {Boolean} [num=false] - Return a number. * @returns {String|Number} @@ -317,7 +313,7 @@ class Amount { * Safely convert a currency string to base unit. * @param {String|Number} value * @param {Number} exp - Exponent. - * @returns {Amount} Base unit. + * @returns {AmountValue} Base unit. * @throws on parse error */ diff --git a/lib/ui/uri.js b/lib/ui/uri.js index cb0ab1757..e95cf51f0 100644 --- a/lib/ui/uri.js +++ b/lib/ui/uri.js @@ -11,12 +11,25 @@ const Address = require('../primitives/address'); const Amount = require('./amount'); const pkg = require('../pkg'); +/** @typedef {import('../types').Amount} AmountValue */ +/** @typedef {import('../types').NetworkType} NetworkType */ +/** @typedef {import('../protocol/network')} Network */ + +/** + * @typedef {Object} URIOptions + * @property {Address} address + * @property {AmountValue?} [amount] + * @property {String?} [label] + * @property {String?} [message] + * @property {String?} [request] + */ + /** * URI * Represents a handshake URI. * @alias module:ui.URI * @property {Address} address - * @property {Amount} amount + * @property {AmountValue} amount * @property {String|null} label * @property {String|null} message * @property {String|null} request @@ -27,14 +40,17 @@ class URI { * Create a handshake URI. * @alias module:ui.URI * @constructor - * @param {Object|String} options + * @param {(URIOptions|String)?} [options] */ constructor(options) { this.address = new Address(); this.amount = -1; + /** @type {String?} */ this.label = null; + /** @type {String?} */ this.message = null; + /** @type {String?} */ this.request = null; if (options) @@ -43,8 +59,7 @@ class URI { /** * Inject properties from options object. - * @private - * @param {Object|String} options + * @param {URIOptions|String} options * @returns {URI} */ @@ -81,7 +96,7 @@ class URI { /** * Instantiate URI from options. - * @param {Object|String} options + * @param {URIOptions|String} options * @returns {URI} */ @@ -93,7 +108,7 @@ class URI { * Parse and inject properties from string. * @private * @param {String} str - * @param {Network?} network + * @param {(NetworkType|Network)?} [network] * @returns {URI} */ @@ -148,7 +163,7 @@ class URI { /** * Instantiate uri from string. * @param {String} str - * @param {Network?} network + * @param {(NetworkType|Network)?} [network] * @returns {URI} */ diff --git a/lib/utils/fixed.js b/lib/utils/fixed.js index 5c3eee094..884fa7c0a 100644 --- a/lib/utils/fixed.js +++ b/lib/utils/fixed.js @@ -28,11 +28,11 @@ exports.encode = function encode(num, exp) { const mult = pow10(exp); - let lo = num % mult; - let hi = (num - lo) / mult; + const nlo = num % mult; + const nhi = (num - nlo) / mult; - lo = lo.toString(10); - hi = hi.toString(10); + let lo = nlo.toString(10); + const hi = nhi.toString(10); while (lo.length < exp) lo = '0' + lo; @@ -100,17 +100,17 @@ exports.decode = function decode(str, exp) { assert(/^\d+$/.test(hi) && /^\d+$/.test(lo), 'Non-numeric characters in fixed number string.'); - hi = parseInt(hi, 10); - lo = parseInt(lo, 10); + const nhi = parseInt(hi, 10); + const nlo = parseInt(lo, 10); const mult = pow10(exp); const maxLo = modSafe(mult); const maxHi = divSafe(mult); - assert(hi < maxHi || (hi === maxHi && lo <= maxLo), + assert(nhi < maxHi || (nhi === maxHi && nlo <= maxLo), 'Fixed number string exceeds 2^53-1.'); - return sign * (hi * mult + lo); + return sign * (nhi * mult + nlo); }; /** diff --git a/lib/utils/hashlist.js b/lib/utils/hashlist.js index a605be033..4430ae3f6 100644 --- a/lib/utils/hashlist.js +++ b/lib/utils/hashlist.js @@ -19,6 +19,10 @@ const DUMMY = Buffer.allocUnsafe(0); */ class HashList { + /** + * @param {Number} size + */ + constructor(size) { assert((size >>> 0) === size); assert((size & 1) === 0); @@ -51,7 +55,12 @@ class HashList { yield this.data.slice(i, i + this.size); } + /** + * @returns {HashList} + */ + clone() { + // @ts-ignore const list = new this.constructor(); list.data = copy(this.data); list.pos = this.pos; diff --git a/lib/utils/util.js b/lib/utils/util.js index e26471793..5da606da5 100644 --- a/lib/utils/util.js +++ b/lib/utils/util.js @@ -14,10 +14,12 @@ const assert = require('bsert'); const util = exports; +/** @typedef {ReturnType} HRTime */ + /** * Return hrtime (shim for browser). - * @param {Array} time - * @returns {Array} [seconds, nanoseconds] + * @param {HRTime?} [time] + * @returns {HRTime|Number} [seconds, nanoseconds] */ util.bench = function bench(time) { @@ -90,7 +92,7 @@ util.time = function time(date) { if (date == null) return util.now(); - return new Date(date) / 1000 | 0; + return Number(new Date(date)) / 1000 | 0; }; /** @@ -101,24 +103,24 @@ util.time = function time(date) { util.hex32 = function hex32(num) { assert((num >>> 0) === num); - num = num.toString(16); - switch (num.length) { + const numStr = num.toString(16); + switch (numStr.length) { case 1: - return `0000000${num}`; + return `0000000${numStr}`; case 2: - return `000000${num}`; + return `000000${numStr}`; case 3: - return `00000${num}`; + return `00000${numStr}`; case 4: - return `0000${num}`; + return `0000${numStr}`; case 5: - return `000${num}`; + return `000${numStr}`; case 6: - return `00${num}`; + return `00${numStr}`; case 7: - return `0${num}`; + return `0${numStr}`; case 8: - return `${num}`; + return `${numStr}`; default: throw new Error(); } From 8fcfa1a5915a58bef07b6d084918a60a239e2df0 Mon Sep 17 00:00:00 2001 From: Nodari Chkuaselidze Date: Sat, 28 Sep 2024 18:24:51 +0400 Subject: [PATCH 3/6] types: update primitives, coins, script and covenants. --- lib/blockchain/chaindb.js | 1 - lib/coins/coinentry.js | 26 ++++---- lib/coins/coins.js | 6 ++ lib/coins/coinview.js | 32 ++++++++-- lib/coins/compress.js | 12 +++- lib/coins/undocoins.js | 15 +++-- lib/covenants/ownership.js | 20 ++++++- lib/covenants/rules.js | 17 ++++-- lib/hd/mnemonic.js | 6 +- lib/hd/private.js | 6 +- lib/hd/public.js | 6 +- lib/net/hostlist.js | 22 +++---- lib/net/netaddress.js | 46 +++++++------- lib/net/packets.js | 81 +++++++++++++------------ lib/net/peer.js | 5 +- lib/primitives/abstractblock.js | 12 ++-- lib/primitives/address.js | 5 +- lib/primitives/airdropkey.js | 63 +++++++++++++++++-- lib/primitives/airdropproof.js | 66 +++++++++++++++++++- lib/primitives/block.js | 47 ++++++++++----- lib/primitives/claim.js | 1 + lib/primitives/coin.js | 34 ++++++----- lib/primitives/covenant.js | 40 +++++++------ lib/primitives/headers.js | 28 +++++---- lib/primitives/input.js | 47 +++++++++------ lib/primitives/invitem.js | 16 +++-- lib/primitives/keyring.js | 48 ++++++++------- lib/primitives/memblock.js | 9 +-- lib/primitives/merkleblock.js | 33 ++++++---- lib/primitives/mtx.js | 69 ++++++++++++--------- lib/primitives/outpoint.js | 43 +++++++------ lib/primitives/output.js | 46 ++++++++------ lib/primitives/tx.js | 103 +++++++++++++++++++------------- lib/primitives/txmeta.js | 32 ++++++---- lib/script/common.js | 5 +- lib/script/opcode.js | 20 ++++--- lib/script/script.js | 72 +++++++++++----------- lib/script/scripterror.js | 6 +- lib/script/scriptnum.js | 12 ++-- lib/script/sigcache.js | 2 + lib/script/stack.js | 22 +++---- lib/script/witness.js | 42 +++++++------ lib/types.js | 15 ++++- lib/wallet/path.js | 18 +++--- lib/workers/workerpool.js | 2 +- 45 files changed, 811 insertions(+), 448 deletions(-) diff --git a/lib/blockchain/chaindb.js b/lib/blockchain/chaindb.js index bda1ddd43..98f012552 100644 --- a/lib/blockchain/chaindb.js +++ b/lib/blockchain/chaindb.js @@ -1177,7 +1177,6 @@ class ChainDB { /** * Get a coin (unspents only). - * @private * @param {Outpoint} prevout * @returns {Promise} - Returns {@link CoinEntry}. */ diff --git a/lib/coins/coinentry.js b/lib/coins/coinentry.js index 01df7d433..b57bb0900 100644 --- a/lib/coins/coinentry.js +++ b/lib/coins/coinentry.js @@ -13,6 +13,10 @@ const Output = require('../primitives/output'); const compress = require('./compress'); const {encoding} = bio; +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('../primitives/outpoint')} Outpoint */ +/** @typedef {import('../primitives/tx')} TX */ + /* * Constants */ @@ -79,8 +83,7 @@ class CoinEntry extends bio.Struct { /** * Inject properties from TX. - * @param {TX} tx - * @param {Number} index + * @param {Output} output */ fromOutput(output) { @@ -90,8 +93,7 @@ class CoinEntry extends bio.Struct { /** * Instantiate a coin from a TX - * @param {TX} tx - * @param {Number} index - Output index. + * @param {Output} output * @returns {CoinEntry} */ @@ -100,9 +102,8 @@ class CoinEntry extends bio.Struct { } /** - * Inject properties from TX. - * @param {TX} tx - * @param {Number} index + * Inject properties from Coin. + * @param {Coin} coin */ fromCoin(coin) { @@ -117,7 +118,7 @@ class CoinEntry extends bio.Struct { /** * Instantiate a coin from a TX - * @param {TX} tx + * @param {Coin} coin * @returns {CoinEntry} */ @@ -129,6 +130,7 @@ class CoinEntry extends bio.Struct { * Inject properties from TX. * @param {TX} tx * @param {Number} index + * @param {Number} height */ fromTX(tx, index, height) { @@ -146,6 +148,7 @@ class CoinEntry extends bio.Struct { * Instantiate a coin from a TX * @param {TX} tx * @param {Number} index - Output index. + * @param {Number} height * @returns {CoinEntry} */ @@ -172,7 +175,8 @@ class CoinEntry extends bio.Struct { /** * Write the coin to a buffer writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -213,8 +217,7 @@ class CoinEntry extends bio.Struct { /** * Inject properties from serialized buffer writer. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -237,7 +240,6 @@ class CoinEntry extends bio.Struct { /** * Inject properties from serialized data. - * @private * @param {Buffer} data */ diff --git a/lib/coins/coins.js b/lib/coins/coins.js index d543196cb..639b567bf 100644 --- a/lib/coins/coins.js +++ b/lib/coins/coins.js @@ -9,6 +9,11 @@ const assert = require('bsert'); const CoinEntry = require('./coinentry'); +/** @typedef {import('../primitives/coin')} Coin */ +/** @typedef {import('../primitives/output')} Output */ +/** @typedef {import('../primitives/tx')} TX */ +/** @typedef {import('../primitives/outpoint')} Outpoint */ + /** * Coins * Represents the outputs for a single transaction. @@ -23,6 +28,7 @@ class Coins { */ constructor() { + /** @type Map */ this.outputs = new Map(); } diff --git a/lib/coins/coinview.js b/lib/coins/coinview.js index eff167f69..b958784bd 100644 --- a/lib/coins/coinview.js +++ b/lib/coins/coinview.js @@ -13,6 +13,17 @@ const CoinEntry = require('./coinentry'); const View = require('../covenants/view'); const {BitView} = require('../covenants/bitfield'); +/** @typedef {import('bufio').BufferReader} BufferReader */ +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('../primitives/coin')} Coin */ +/** @typedef {import('../primitives/input')} Input */ +/** @typedef {import('../primitives/output')} Output */ +/** @typedef {import('../primitives/tx')} TX */ +/** @typedef {import('../primitives/outpoint')} Outpoint */ +/** @typedef {import('../wallet/path')} Path */ +/** @typedef {import('../blockchain/chaindb')} ChainDB */ + /** * Coin View * Represents a coin viewpoint: @@ -84,8 +95,8 @@ class CoinView extends View { /** * Remove coins from the collection. - * @param {Coins} coins - * @returns {Coins|null} + * @param {Hash} hash + * @returns {Coins?} */ remove(hash) { @@ -400,6 +411,18 @@ class CoinView extends View { return null; } + /** + * Add an HD path to the collection. + * Implemented in {@link WalletCoinView} + * @param {Outpoint} prevout + * @param {Path} path + * @returns {Path|null} + */ + + addPath(prevout, path) { + return null; + } + /** * Get coins height by input. * @param {Input} input @@ -497,6 +520,7 @@ class CoinView extends View { /** * Calculate serialization size. + * @param {TX} tx * @returns {Number} */ @@ -520,8 +544,9 @@ class CoinView extends View { /** * Write coin data to buffer writer * as it pertains to a transaction. - * @param {BufferWriter} bw + * @param {BufioWriter} bw * @param {TX} tx + * @returns {BufioWriter} */ write(bw, tx) { @@ -543,7 +568,6 @@ class CoinView extends View { /** * Read serialized view data from a buffer * reader as it pertains to a transaction. - * @private * @param {BufferReader} br * @param {TX} tx */ diff --git a/lib/coins/compress.js b/lib/coins/compress.js index 282db09d7..be9ea8793 100644 --- a/lib/coins/compress.js +++ b/lib/coins/compress.js @@ -6,6 +6,11 @@ 'use strict'; +/** @typedef {import('bufio').BufferReader} BufferReader */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('../types').Amount} AmountValue */ +/** @typedef {import('../primitives/output')} Output */ + /** * @module coins/compress * @ignore @@ -16,7 +21,7 @@ const {encoding} = require('bufio'); /** * Compress an output. * @param {Output} output - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ function compressOutput(output, bw) { @@ -41,6 +46,7 @@ function decompressOutput(output, br) { /** * Calculate output size. + * @param {Output} output * @returns {Number} */ @@ -56,7 +62,7 @@ function sizeOutput(output) { * Compress value using an exponent. Takes advantage of * the fact that many values are divisible by 10. * @see https://github.com/btcsuite/btcd/blob/master/blockchain/compress.go - * @param {Amount} value + * @param {AmountValue} value * @returns {Number} */ @@ -82,7 +88,7 @@ function compressValue(value) { /** * Decompress value. * @param {Number} value - Compressed value. - * @returns {Amount} value + * @returns {AmountValue} value */ function decompressValue(value) { diff --git a/lib/coins/undocoins.js b/lib/coins/undocoins.js index f60fffa88..dbcfb0251 100644 --- a/lib/coins/undocoins.js +++ b/lib/coins/undocoins.js @@ -10,6 +10,10 @@ const assert = require('bsert'); const bio = require('bufio'); const CoinEntry = require('../coins/coinentry'); +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('../primitives/outpoint')} Outpoint */ +/** @typedef {import('./coinview')} CoinView */ + /** * Undo Coins * Coins need to be resurrected from somewhere @@ -28,12 +32,13 @@ class UndoCoins extends bio.Struct { constructor() { super(); + /** @type {CoinEntry[]} */ this.items = []; } /** * Push coin entry onto undo coin array. - * @param {CoinEntry} + * @param {CoinEntry} coin * @returns {Number} */ @@ -59,7 +64,8 @@ class UndoCoins extends bio.Struct { /** * Serialize all undo coins. - * @returns {Buffer} + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -73,9 +79,8 @@ class UndoCoins extends bio.Struct { /** * Inject properties from serialized data. - * @private - * @param {Buffer} data - * @returns {UndoCoins} + * @param {bio.BufferReader} br + * @returns {this} */ read(br) { diff --git a/lib/covenants/ownership.js b/lib/covenants/ownership.js index 6defc4fc4..5f7a9f29a 100644 --- a/lib/covenants/ownership.js +++ b/lib/covenants/ownership.js @@ -18,12 +18,15 @@ const Network = require('../protocol/network'); const reserved = require('./reserved'); const {Proof: BNSProof} = BNSOwnership; +/** @typedef {import('../types').NetworkType} NetworkType */ + /* * Constants */ const EMPTY = Buffer.alloc(0); +/** @type {Ownership} */ let ownership = null; /** @@ -35,6 +38,11 @@ class Proof extends BNSProof { super(); } + /** + * @param {Buffer} data + * @returns {this} + */ + decode(data) { const br = bio.read(data); @@ -49,6 +57,10 @@ class Proof extends BNSProof { return this; } + /** + * @returns {String[]} + */ + getNames() { const target = this.getTarget(); @@ -58,6 +70,10 @@ class Proof extends BNSProof { return [util.label(target, 0), target]; } + /** + * @returns {String} + */ + getName() { return this.getNames()[0]; } @@ -288,9 +304,9 @@ ownership = new Ownership(); * Expose */ -module.exports = Ownership; - Ownership.Proof = Proof; Ownership.OwnershipProof = Proof; Ownership.ProofData = ProofData; Ownership.ownership = ownership; + +module.exports = Ownership; diff --git a/lib/covenants/rules.js b/lib/covenants/rules.js index fc4bcf947..9156d8d90 100644 --- a/lib/covenants/rules.js +++ b/lib/covenants/rules.js @@ -14,10 +14,17 @@ const sha3 = require('bcrypto/lib/sha3'); const consensus = require('../protocol/consensus'); const reserved = require('./reserved'); const {locked} = require('./locked'); -const {OwnershipProof} = require('./ownership'); +const OwnershipProof = require('./ownership').OwnershipProof; const AirdropProof = require('../primitives/airdropproof'); const rules = exports; +/** @typedef {import('../types').Amount} AmountValue */ +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../protocol/network')} Network */ +/** @typedef {import('../primitives/tx')} TX */ +/** @typedef {import('../coins/coinview')} CoinView */ +/** @typedef {import('./ownership').OwnershipProof} OwnershipProof */ + /* * Constants */ @@ -199,7 +206,7 @@ rules.verifyName = function verifyName(name) { /** * Verify a domain name meets handshake requirements. - * @param {String} name + * @param {String} str * @returns {Boolean} */ @@ -246,7 +253,7 @@ rules.verifyString = function verifyString(str) { /** * Verify a domain name meets handshake requirements. - * @param {Buffer} name + * @param {Buffer} buf * @returns {Boolean} */ @@ -435,7 +442,7 @@ rules.isLockedUp = function isLockedUp(nameHash, height, network) { /** * Create a blind bid hash from a value and nonce. - * @param {Amount} value + * @param {AmountValue} value * @param {Buffer} nonce * @returns {Buffer} */ @@ -765,6 +772,7 @@ rules.hasSaneCovenants = function hasSaneCovenants(tx) { if (!key.equals(nameHash)) return false; + /** @type {OwnershipProof} */ let proof; try { @@ -1173,6 +1181,7 @@ rules.verifyCovenants = function verifyCovenants(tx, view, height, network) { if (witness.items.length !== 1) return -1; + /** @type {OwnershipProof} */ let proof; try { proof = OwnershipProof.decode(witness.items[0]); diff --git a/lib/hd/mnemonic.js b/lib/hd/mnemonic.js index 20e9f0ea4..7028d7caa 100644 --- a/lib/hd/mnemonic.js +++ b/lib/hd/mnemonic.js @@ -17,6 +17,8 @@ const wordlist = require('./wordlist'); const common = require('./common'); const nfkd = require('./nfkd'); +/** @typedef {import('../types').BufioWriter} BufioWriter */ + /* * Constants */ @@ -404,8 +406,8 @@ class Mnemonic extends bio.Struct { /** * Write the mnemonic to a buffer writer. - * @param {bio.BufferWriter} bw - * @returns {bio.BufferWriter} + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { diff --git a/lib/hd/private.js b/lib/hd/private.js index 29a9d3745..dfe34a4ec 100644 --- a/lib/hd/private.js +++ b/lib/hd/private.js @@ -23,6 +23,7 @@ const HDPublicKey = require('./public'); /** @typedef {import('../types').Base58String} Base58String */ /** @typedef {import('../types').NetworkType} NetworkType */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ /* * Constants @@ -603,8 +604,9 @@ class HDPrivateKey extends bio.Struct { /** * Write the key to a buffer writer. - * @param {bio.BufferWriter} bw - * @param {(Network|NetworkType)?} network + * @param {BufioWriter} bw + * @param {(Network|NetworkType)?} [network] + * @returns {BufioWriter} */ write(bw, network) { diff --git a/lib/hd/public.js b/lib/hd/public.js index 1d68d5320..f8f263056 100644 --- a/lib/hd/public.js +++ b/lib/hd/public.js @@ -20,6 +20,7 @@ const common = require('./common'); /** @typedef {import('../types').Base58String} Base58String */ /** @typedef {import('../types').NetworkType} NetworkType */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ /** @typedef {String} HDPublicKeyID */ /** @@ -449,8 +450,9 @@ class HDPublicKey extends bio.Struct { /** * Write the key to a buffer writer. - * @param {bio.BufferWriter} bw - * @param {(Network|NetworkType)?} network + * @param {BufioWriter} bw + * @param {(Network|NetworkType)?} [network] + * @returns {BufioWriter} */ write(bw, network) { diff --git a/lib/net/hostlist.js b/lib/net/hostlist.js index fe9f9dd31..595815374 100644 --- a/lib/net/hostlist.js +++ b/lib/net/hostlist.js @@ -219,8 +219,6 @@ class HostList { /** * Read and initialize from hosts file. - * @method - * @returns {Promise} */ injectSeeds() { @@ -464,7 +462,7 @@ class HostList { * Get fresh bucket for host. * @private * @param {HostEntry} entry - * @param {NetAddress?} src + * @param {NetAddress?} [src] * @returns {Map} */ @@ -534,7 +532,7 @@ class HostList { /** * Add host to host list. * @param {NetAddress} addr - * @param {NetAddress?} src + * @param {NetAddress?} [src] * @returns {Boolean} */ @@ -889,7 +887,7 @@ class HostList { addSeed(host) { const ip = IP.fromHostname(host); - if (ip.type === IP.types.DNS) { + if (ip.type === IP.types.NONE) { // Defer for resolution. this.dnsSeeds.push(ip); return null; @@ -914,7 +912,7 @@ class HostList { addNode(host) { const ip = IP.fromHostname(host); - if (ip.type === IP.types.DNS) { + if (ip.type === IP.types.NONE) { // Defer for resolution. this.dnsNodes.push(ip); return null; @@ -1163,7 +1161,7 @@ class HostList { async populate(target) { const addrs = []; - assert(target.type === IP.types.DNS, 'Resolved host passed.'); + assert(target.type === IP.types.NONE, 'Resolved host passed.'); this.logger.info('Resolving host: %s.', target.host); @@ -1465,8 +1463,8 @@ class HostEntry { /** * Create a host entry. * @constructor - * @param {NetAddress} addr - * @param {NetAddress} src + * @param {NetAddress} [addr] + * @param {NetAddress} [src] */ constructor(addr, src) { @@ -1841,7 +1839,5 @@ function random(max) { * Expose */ -exports = HostList; -exports.HostEntry = HostEntry; - -module.exports = exports; +HostList.HostEntry = HostEntry; +module.exports = HostList; diff --git a/lib/net/netaddress.js b/lib/net/netaddress.js index f949df677..79a12fdbf 100644 --- a/lib/net/netaddress.js +++ b/lib/net/netaddress.js @@ -14,6 +14,10 @@ const Network = require('../protocol/network'); const util = require('../utils/util'); const common = require('./common'); +/** @typedef {import('net').Socket} NetSocket */ +/** @typedef {import('../types').NetworkType} NetworkType */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ + /* * Constants */ @@ -34,7 +38,7 @@ class NetAddress extends bio.Struct { /** * Create a network address. * @constructor - * @param {Object} options + * @param {Object} [options] * @param {Number?} options.time - Timestamp. * @param {Number?} options.services - Service bits. * @param {String?} options.host - IP address (IPv6 or IPv4). @@ -58,7 +62,6 @@ class NetAddress extends bio.Struct { /** * Inject properties from options object. - * @private * @param {Object} options */ @@ -217,6 +220,7 @@ class NetAddress extends bio.Struct { /** * Compare against another network address. + * @param {NetAddress} addr * @returns {Boolean} */ @@ -226,6 +230,7 @@ class NetAddress extends bio.Struct { /** * Compare against another network address. + * @param {NetAddress} addr * @returns {Number} */ @@ -326,10 +331,10 @@ class NetAddress extends bio.Struct { /** * Inject properties from host, port, and network. - * @private * @param {String} host * @param {Number} port - * @param {(Network|NetworkType)?} network + * @param {Buffer} [key] + * @param {(Network|NetworkType)?} [network] */ fromHost(host, port, key, network) { @@ -355,7 +360,8 @@ class NetAddress extends bio.Struct { * from a host and port. * @param {String} host * @param {Number} port - * @param {(Network|NetworkType)?} network + * @param {Buffer} [key] + * @param {(Network|NetworkType)?} [network] * @returns {NetAddress} */ @@ -365,9 +371,8 @@ class NetAddress extends bio.Struct { /** * Inject properties from hostname and network. - * @private * @param {String} hostname - * @param {(Network|NetworkType)?} network + * @param {(Network|NetworkType)?} [network] */ fromHostname(hostname, network) { @@ -385,7 +390,7 @@ class NetAddress extends bio.Struct { * Instantiate a network address * from a hostname (i.e. 127.0.0.1:8333). * @param {String} hostname - * @param {(Network|NetworkType)?} network + * @param {(Network|NetworkType)?} [network] * @returns {NetAddress} */ @@ -395,8 +400,8 @@ class NetAddress extends bio.Struct { /** * Inject properties from socket. - * @private - * @param {net.Socket} socket + * @param {NetSocket} socket + * @param {(Network|NetworkType)?} [network] */ fromSocket(socket, network) { @@ -410,12 +415,13 @@ class NetAddress extends bio.Struct { /** * Instantiate a network address * from a socket. - * @param {net.Socket} socket + * @param {NetSocket} socket + * @param {(Network|NetworkType)?} [network] * @returns {NetAddress} */ - static fromSocket(hostname, network) { - return new this().fromSocket(hostname, network); + static fromSocket(socket, network) { + return new this().fromSocket(socket, network); } /** @@ -429,8 +435,8 @@ class NetAddress extends bio.Struct { /** * Write network address to a buffer writer. - * @param {BufferWriter} bw - * @returns {Buffer} + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -442,13 +448,12 @@ class NetAddress extends bio.Struct { bw.fill(0, 20); // reserved bw.writeU16(this.port); bw.writeBytes(this.key); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -493,9 +498,8 @@ class NetAddress extends bio.Struct { /** * Inject properties from json object. - * @private * @param {Object} json - * @returns {NetAddress} + * @returns {this} */ fromJSON(json) { @@ -544,7 +548,7 @@ NetAddress.DEFAULT_SERVICES = 0 /** * @param {NetAddress} addr - * @returns {Number} + * @returns {Buffer} */ function groupKey(addr) { diff --git a/lib/net/packets.js b/lib/net/packets.js index 5151c3471..6a38a8783 100644 --- a/lib/net/packets.js +++ b/lib/net/packets.js @@ -30,6 +30,9 @@ const AirdropProof = require('../primitives/airdropproof'); const {encoding} = bio; const DUMMY = Buffer.alloc(0); +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ + /** * Packet types. * @enum {Number} @@ -156,15 +159,15 @@ class VersionPacket extends Packet { /** * Create a version packet. * @constructor - * @param {Object?} options - * @param {Number} options.version - Protocol version. - * @param {Number} options.services - Service bits. - * @param {Number} options.time - Timestamp of discovery. - * @param {NetAddress} options.remote - Their address. - * @param {Buffer} options.nonce - * @param {String} options.agent - User agent string. - * @param {Number} options.height - Chain height. - * @param {Boolean} options.noRelay - Whether transactions + * @param {Object} [options] + * @param {Number?} options.version - Protocol version. + * @param {Number?} options.services - Service bits. + * @param {Number?} options.time - Timestamp of discovery. + * @param {NetAddress?} options.remote - Their address. + * @param {Buffer?} options.nonce + * @param {String?} options.agent - User agent string. + * @param {Number?} options.height - Chain height. + * @param {Boolean?} options.noRelay - Whether transactions * should be relayed immediately. */ @@ -173,6 +176,7 @@ class VersionPacket extends Packet { this.type = exports.types.VERSION; + /** @type {Number} */ this.version = common.PROTOCOL_VERSION; this.services = common.LOCAL_SERVICES; this.time = util.now(); @@ -188,7 +192,6 @@ class VersionPacket extends Packet { /** * Inject properties from options. - * @private * @param {Object} options */ @@ -238,7 +241,8 @@ class VersionPacket extends Packet { /** * Write version packet to buffer writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -252,13 +256,13 @@ class VersionPacket extends Packet { bw.writeString(this.agent, 'ascii'); bw.writeU32(this.height); bw.writeU8(this.noRelay ? 1 : 0); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br + * @returns {this} */ read(br) { @@ -329,18 +333,18 @@ class PingPacket extends Packet { /** * Serialize ping packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { bw.writeBytes(this.nonce); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -381,18 +385,18 @@ class PongPacket extends Packet { /** * Serialize pong packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { bw.writeBytes(this.nonce); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -454,7 +458,8 @@ class AddrPacket extends Packet { /** * Serialize addr packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -463,13 +468,12 @@ class AddrPacket extends Packet { for (const item of this.items) item.write(bw); - return this; + return bw; } /** * Inject properties from serialized data. - * @private - * @param {Buffer} data + * @param {bio.BufferReader} br */ read(br) { @@ -500,6 +504,7 @@ class InvPacket extends Packet { this.type = exports.types.INV; + /** @type {InvItem[]} */ this.items = items || []; } @@ -517,7 +522,8 @@ class InvPacket extends Packet { /** * Serialize inv packet to writer. - * @param {Buffer} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -528,13 +534,12 @@ class InvPacket extends Packet { for (const item of this.items) item.write(bw); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -624,7 +629,8 @@ class GetBlocksPacket extends Packet { /** * Serialize getblocks packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -637,13 +643,12 @@ class GetBlocksPacket extends Packet { bw.writeHash(this.stop); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -718,7 +723,8 @@ class HeadersPacket extends Packet { /** * Serialize headers packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -729,13 +735,12 @@ class HeadersPacket extends Packet { for (const item of this.items) item.write(bw); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { diff --git a/lib/net/peer.js b/lib/net/peer.js index 96b3bdcca..c502fab71 100644 --- a/lib/net/peer.js +++ b/lib/net/peer.js @@ -34,6 +34,8 @@ const services = common.services; const invTypes = InvItem.types; const packetTypes = packets.types; +/** @typedef {import('net').Socket} NetSocket */ + /** * Represents a network peer. * @alias module:net.Peer @@ -141,7 +143,8 @@ class Peer extends EventEmitter { /** * Create inbound peer from socket. * @param {PeerOptions} options - * @param {net.Socket} socket + * @param {NetSocket} socket + * @param {Boolean} encrypted * @returns {Peer} */ diff --git a/lib/primitives/abstractblock.js b/lib/primitives/abstractblock.js index edbc476b5..0d6f8bbcc 100644 --- a/lib/primitives/abstractblock.js +++ b/lib/primitives/abstractblock.js @@ -15,6 +15,7 @@ const consensus = require('../protocol/consensus'); const util = require('../utils/util'); /** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ /** * Abstract Block @@ -52,13 +53,14 @@ class AbstractBlock extends bio.Struct { this.mutable = false; + /** @type {Buffer?} */ this._hash = null; + /** @type {Buffer?} */ this._maskHash = null; } /** * Inject properties from options object. - * @private * @param {Object} options */ @@ -99,7 +101,6 @@ class AbstractBlock extends bio.Struct { /** * Inject properties from json object. - * @private * @param {Object} json */ @@ -197,8 +198,8 @@ class AbstractBlock extends bio.Struct { /** * Inject properties from serialized data. - * @private * @param {Buffer} data + * @returns {this} */ fromHead(data) { @@ -416,7 +417,8 @@ class AbstractBlock extends bio.Struct { /** * Serialize the block headers. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ writeHead(bw) { @@ -442,7 +444,7 @@ class AbstractBlock extends bio.Struct { /** * Parse the block headers. - * @param {BufferReader} br + * @param {bio.BufferReader} br */ readHead(br) { diff --git a/lib/primitives/address.js b/lib/primitives/address.js index 2bb65be04..c1b07e8bf 100644 --- a/lib/primitives/address.js +++ b/lib/primitives/address.js @@ -16,6 +16,7 @@ const consensus = require('../protocol/consensus'); /** @typedef {import('../types').Hash} Hash */ /** @typedef {import('../types').NetworkType} NetworkType */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ /** @typedef {import('../script/script')} Script */ /** @typedef {import('../script/witness')} Witness */ @@ -412,8 +413,8 @@ class Address extends bio.Struct { /** * Write address to buffer writer. - * @param {bio.BufferWriter} bw - * @returns {bio.BufferWriter} + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { diff --git a/lib/primitives/airdropkey.js b/lib/primitives/airdropkey.js index 1cc167aa7..5e121a0bb 100644 --- a/lib/primitives/airdropkey.js +++ b/lib/primitives/airdropkey.js @@ -14,6 +14,10 @@ const ed25519 = require('bcrypto/lib/ed25519'); const {countLeft} = require('bcrypto/lib/encoding/util'); const Goo = require('goosig'); +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').Amount} AmountValue */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ + /* * Goo */ @@ -62,6 +66,11 @@ class AirdropKey extends bio.Struct { this.tweak = null; } + /** + * @param {AirdropKey} key + * @returns {this} + */ + inject(key) { assert(key instanceof AirdropKey); @@ -107,6 +116,10 @@ class AirdropKey extends bio.Struct { return countLeft(this.n) < 2048 - 7; } + /** + * @returns {Boolean} + */ + validate() { switch (this.type) { case keyTypes.RSA: { @@ -147,6 +160,12 @@ class AirdropKey extends bio.Struct { } } + /** + * @param {Buffer} msg + * @param {Buffer} sig + * @returns {Boolean} + */ + verify(msg, sig) { assert(Buffer.isBuffer(msg)); assert(Buffer.isBuffer(sig)); @@ -186,6 +205,10 @@ class AirdropKey extends bio.Struct { } } + /** + * @returns {Hash} + */ + hash() { const bw = bio.pool(this.getSize()); this.write(bw); @@ -232,6 +255,11 @@ class AirdropKey extends bio.Struct { return size; } + /** + * @param {BufioWriter} bw + * @returns {BufioWriter} + */ + write(bw) { bw.writeU8(this.type); @@ -265,6 +293,11 @@ class AirdropKey extends bio.Struct { return bw; } + /** + * @param {bio.BufferReader} br + * @returns {this} + */ + read(br) { this.type = br.readU8(); @@ -309,6 +342,13 @@ class AirdropKey extends bio.Struct { return this; } + /** + * @param {String} addr + * @param {AmountValue} value + * @param {Boolean} sponsor + * @returns {this} + */ + fromAddress(addr, value, sponsor = false) { assert(typeof addr === 'string'); assert(Number.isSafeInteger(value) && value >= 0); @@ -360,6 +400,11 @@ class AirdropKey extends bio.Struct { }; } + /** + * @param {Object} json + * @returns {this} + */ + fromJSON(json) { assert(json && typeof json === 'object'); assert(typeof json.type === 'string'); @@ -367,11 +412,12 @@ class AirdropKey extends bio.Struct { this.type = keyTypes[json.type]; + console.log(base16.decode.toString()); switch (this.type) { case keyTypes.RSA: { this.n = base16.decode(json.n); this.e = base16.decode(json.e); - this.nonce = base16.decode(json.nonce, 32); + this.nonce = base16.decode(json.nonce); break; } @@ -381,14 +427,14 @@ class AirdropKey extends bio.Struct { } case keyTypes.P256: { - this.point = base16.decode(json.point, 33); - this.nonce = base16.decode(json.nonce, 32); + this.point = base16.decode(json.point); + this.nonce = base16.decode(json.nonce); break; } case keyTypes.ED25519: { - this.point = base16.decode(json.point, 32); - this.nonce = base16.decode(json.nonce, 32); + this.point = base16.decode(json.point); + this.nonce = base16.decode(json.nonce); break; } @@ -411,6 +457,13 @@ class AirdropKey extends bio.Struct { return this; } + /** + * @param {String} addr + * @param {AmountValue} value + * @param {Boolean} sponsor + * @returns {AirdropKey} + */ + static fromAddress(addr, value, sponsor) { return new this().fromAddress(addr, value, sponsor); } diff --git a/lib/primitives/airdropproof.js b/lib/primitives/airdropproof.js index eed3d00ff..00dabf097 100644 --- a/lib/primitives/airdropproof.js +++ b/lib/primitives/airdropproof.js @@ -11,6 +11,9 @@ const InvItem = require('./invitem'); const consensus = require('../protocol/consensus'); const {keyTypes} = AirdropKey; +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ + /* * Constants */ @@ -45,6 +48,8 @@ const TREE_LEAVES = AIRDROP_LEAVES + FAUCET_LEAVES; const MAX_PROOF_SIZE = 3400; // 3253 +/** @typedef {ReturnType} AirdropProofJSON */ + /** * AirdropProof */ @@ -53,8 +58,10 @@ class AirdropProof extends bio.Struct { constructor() { super(); this.index = 0; + /** @type {Hash[]} */ this.proof = []; this.subindex = 0; + /** @type {Hash[]} */ this.subproof = []; this.key = EMPTY; this.version = 0; @@ -87,6 +94,12 @@ class AirdropProof extends bio.Struct { return size; } + /** + * @param {BufioWriter} bw + * @param {Boolean} [sighash=false] + * @returns {BufioWriter} + */ + write(bw, sighash = false) { if (sighash) bw.writeBytes(CONTEXT); @@ -115,6 +128,11 @@ class AirdropProof extends bio.Struct { return bw; } + /** + * @param {Buffer} data + * @returns {this} + */ + decode(data) { const br = bio.read(data); @@ -129,6 +147,11 @@ class AirdropProof extends bio.Struct { return this; } + /** + * @param {bio.BufferReader} br + * @returns {this} + */ + read(br) { this.index = br.readU32(); assert(this.index < AIRDROP_LEAVES); @@ -169,12 +192,21 @@ class AirdropProof extends bio.Struct { return this; } + /** + * @returns {Buffer} + */ + hash() { const bw = bio.pool(this.getSize()); this.write(bw); return blake2b.digest(bw.render()); } + /** + * @param {Hash} [expect] + * @returns {Boolean} + */ + verifyMerkle(expect) { if (expect == null) { expect = this.isAddress() @@ -201,6 +233,10 @@ class AirdropProof extends bio.Struct { return root.equals(expect); } + /** + * @returns {Buffer} + */ + signatureData() { const size = this.getSize(true); const bw = bio.pool(size); @@ -210,10 +246,18 @@ class AirdropProof extends bio.Struct { return bw.render(); } + /** + * @returns {Buffer} + */ + signatureHash() { return sha256.digest(this.signatureData()); } + /** + * @returns {AirdropKey|null} + */ + getKey() { try { return AirdropKey.decode(this.key); @@ -222,6 +266,10 @@ class AirdropProof extends bio.Struct { } } + /** + * @returns {Boolean} + */ + verifySignature() { const key = this.getKey(); @@ -244,6 +292,10 @@ class AirdropProof extends bio.Struct { return key.verify(msg, this.signature); } + /** + * @returns {Number} + */ + position() { let index = this.index; @@ -378,6 +430,11 @@ class AirdropProof extends bio.Struct { return true; } + /** + * @param {Hash} [expect] + * @returns {Boolean} + */ + verify(expect) { if (!this.isSane()) return false; @@ -407,6 +464,11 @@ class AirdropProof extends bio.Struct { }; } + /** + * @param {AirdropProofJSON} json + * @returns {this} + */ + fromJSON(json) { assert(json && typeof json === 'object'); assert((json.index >>> 0) === json.index); @@ -422,12 +484,12 @@ class AirdropProof extends bio.Struct { this.index = json.index; for (const hash of json.proof) - this.proof.push(base16.decode(hash, 32)); + this.proof.push(base16.decode(hash)); this.subindex = json.subindex; for (const hash of json.subproof) - this.subproof.push(base16.decode(hash, 32)); + this.subproof.push(base16.decode(hash)); if (json.key) this.key = AirdropKey.fromJSON(json.key).encode(); diff --git a/lib/primitives/block.js b/lib/primitives/block.js index 33af82c16..ab6102c1a 100644 --- a/lib/primitives/block.js +++ b/lib/primitives/block.js @@ -20,6 +20,13 @@ const Network = require('../protocol/network'); const util = require('../utils/util'); const {encoding} = bio; +/** @typedef {import('@handshake-org/bfilter').BloomFilter} BloomFilter */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').Amount} AmountValue */ +/** @typedef {import('../types').RawBlock} RawBlock */ +/** @typedef {import('../coins/coinview')} CoinView */ + /** * Block * Represents a full block. @@ -31,15 +38,18 @@ class Block extends AbstractBlock { /** * Create a block. * @constructor - * @param {Object} options + * @param {Object} [options] */ constructor(options) { super(); + /** @type {TX[]} */ this.txs = []; + /** @type {Buffer?} */ this._raw = null; + /** @type {Sizes?} */ this._sizes = null; if (options) @@ -48,7 +58,6 @@ class Block extends AbstractBlock { /** * Inject properties from options object. - * @private * @param {Object} options */ @@ -68,7 +77,8 @@ class Block extends AbstractBlock { /** * Clear any cached values. - * @param {Boolean?} all - Clear transactions. + * @param {Boolean?} [all] - Clear transactions. + * @returns {this} */ refresh(all) { @@ -286,7 +296,7 @@ class Block extends AbstractBlock { /** * Get the "claimed" reward by the coinbase. - * @returns {Amount} claimed + * @returns {AmountValue} claimed */ getClaimed() { @@ -317,8 +327,8 @@ class Block extends AbstractBlock { /** * Inspect the block and return a more * user-friendly representation of the data. - * @param {CoinView} view - * @param {Number} height + * @param {CoinView} [view] + * @param {Number} [height] * @returns {Object} */ @@ -349,10 +359,10 @@ class Block extends AbstractBlock { /** * Convert the block to an object suitable * for JSON serialization. - * @param {Network} network - * @param {CoinView} view - * @param {Number} height - * @param {Number} depth + * @param {Network} [network] + * @param {CoinView} [view] + * @param {Number} [height] + * @param {Number} [depth] * @returns {Object} */ @@ -381,7 +391,6 @@ class Block extends AbstractBlock { /** * Inject properties from json object. - * @private * @param {Object} json */ @@ -399,8 +408,7 @@ class Block extends AbstractBlock { /** * Inject properties from serialized data. - * @private - * @param {Buffer} data + * @param {bio.BufferReader} br */ read(br) { @@ -430,7 +438,7 @@ class Block extends AbstractBlock { /** * Convert the Block to a MerkleBlock. - * @param {Bloom} filter - Bloom filter for transactions + * @param {BloomFilter} filter - Bloom filter for transactions * to match. The merkle block will contain only the * matched transactions. * @returns {MerkleBlock} @@ -440,6 +448,11 @@ class Block extends AbstractBlock { return MerkleBlock.fromBlock(this, filter); } + /** + * @param {BufioWriter} bw + * @returns {BufioWriter} + */ + write(bw) { if (this._raw) { bw.writeBytes(this._raw); @@ -456,6 +469,10 @@ class Block extends AbstractBlock { return bw; } + /** + * @returns {Buffer} + */ + encode() { if (this.mutable) return super.encode(); @@ -477,7 +494,7 @@ class Block extends AbstractBlock { /** * Get real block size with witness. - * @returns {RawBlock} + * @returns {Sizes} */ getSizes() { diff --git a/lib/primitives/claim.js b/lib/primitives/claim.js index 470212648..37dab00f5 100644 --- a/lib/primitives/claim.js +++ b/lib/primitives/claim.js @@ -38,6 +38,7 @@ class Claim extends bio.Struct { this.blob = EMPTY; + /** @type {Hash?} */ this._hash = null; this._data = null; } diff --git a/lib/primitives/coin.js b/lib/primitives/coin.js index 59a37d300..a1d64a875 100644 --- a/lib/primitives/coin.js +++ b/lib/primitives/coin.js @@ -14,6 +14,12 @@ const consensus = require('../protocol/consensus'); const Outpoint = require('./outpoint'); const util = require('../utils/util'); +/** @typedef {import('bufio').BufferWriter} BufferWriter */ +/** @typedef {import('bufio').BufferReader} BufferReader */ +/** @typedef {import('../types').NetworkType} NetworkType */ +/** @typedef {import('../types').HexHash} HexHash */ +/** @typedef {import('./tx')} TX */ + /** * Coin * Represents an unspent output. @@ -32,7 +38,7 @@ class Coin extends Output { /** * Create a coin. * @constructor - * @param {Object} options + * @param {Object?} [options] */ constructor(options) { @@ -50,8 +56,7 @@ class Coin extends Output { /** * Inject options into coin. - * @private - * @param {Object} options + * @param {Object} [options] */ fromOptions(options) { @@ -107,17 +112,17 @@ class Coin extends Output { /** * Clone the coin. - * @private - * @returns {Coin} + * @returns {this} */ clone() { assert(false, 'Coins are not cloneable.'); + return this; } /** * Calculate number of confirmations since coin was created. - * @param {Number?} height - Current chain height. Network + * @param {Number} height - Current chain height. Network * height is used if not passed in. * @return {Number} */ @@ -140,7 +145,7 @@ class Coin extends Output { /** * Serialize coin to a key * suitable for a hash table. - * @returns {String} + * @returns {Buffer} */ toKey() { @@ -149,8 +154,7 @@ class Coin extends Output { /** * Inject properties from hash table key. - * @private - * @param {String} key + * @param {Buffer} key * @returns {Coin} */ @@ -163,7 +167,7 @@ class Coin extends Output { /** * Instantiate coin from hash table key. - * @param {String} key + * @param {Buffer} key * @returns {Coin} */ @@ -203,8 +207,8 @@ class Coin extends Output { /** * Convert the coin to an object suitable * for JSON serialization. - * @param {Network} network - * @param {Boolean} minimal + * @param {Network} [network] + * @param {Boolean} [minimal] * @returns {Object} */ @@ -225,8 +229,8 @@ class Coin extends Output { /** * Inject JSON properties into coin. - * @private * @param {Object} json + * @param {(NetworkType|Network)?} [network] */ fromJSON(json, network) { @@ -267,6 +271,7 @@ class Coin extends Output { /** * Write the coin to a buffer writer. * @param {BufferWriter} bw + * @returns {BufferWriter} */ write(bw) { @@ -287,7 +292,6 @@ class Coin extends Output { /** * Inject properties from serialized buffer writer. - * @private * @param {BufferReader} br */ @@ -309,6 +313,7 @@ class Coin extends Output { * Inject properties from TX. * @param {TX} tx * @param {Number} index + * @param {Number} height */ fromTX(tx, index, height) { @@ -330,6 +335,7 @@ class Coin extends Output { * Instantiate a coin from a TX * @param {TX} tx * @param {Number} index - Output index. + * @param {Number} height - Chain height. * @returns {Coin} */ diff --git a/lib/primitives/covenant.js b/lib/primitives/covenant.js index dc2d509b1..db983e980 100644 --- a/lib/primitives/covenant.js +++ b/lib/primitives/covenant.js @@ -14,6 +14,13 @@ const consensus = require('../protocol/consensus'); const {encoding} = bio; const {types, typesByVal} = rules; +/** @typedef {import('@handshake-org/bfilter').BloomFilter} BloomFilter */ +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('./address')} Address */ + +/** @typedef {ReturnType} CovenantJSON */ + /** * Covenant * @alias module:primitives.Covenant @@ -26,6 +33,8 @@ class Covenant extends bio.Struct { /** * Create a covenant. * @constructor + * @param {rules.types|Object} [type] + * @param {Buffer[]} [items] */ constructor(type, items) { @@ -40,10 +49,9 @@ class Covenant extends bio.Struct { /** * Inject properties from options object. - * @private - * @param {types} type - * @param {Buffer[]} items - * @returns {Covenant} + * @param {rules.types|Object} [type] + * @param {Buffer[]} [items] + * @returns {this} */ fromOptions(type, items) { @@ -104,7 +112,7 @@ class Covenant extends bio.Struct { /** * Push an item. * @param {Buffer} item - * @returns {Coventant} + * @returns {this} */ push(item) { @@ -666,9 +674,8 @@ class Covenant extends bio.Struct { /** * Inject properties from covenant. * Used for cloning. - * @private - * @param {Covenant} covenant - * @returns {Covenant} + * @param {this} covenant + * @returns {this} */ inject(covenant) { @@ -680,7 +687,7 @@ class Covenant extends bio.Struct { /** * Test the covenant against a bloom filter. - * @param {Bloom} filter + * @param {BloomFilter} filter * @returns {Boolean} */ @@ -738,8 +745,8 @@ class Covenant extends bio.Struct { /** * Write covenant to a buffer writer. - * @param {BufferWriter} bw - * @returns {BufferWriter} + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -765,7 +772,6 @@ class Covenant extends bio.Struct { /** * Convert covenant to a hex string. - * @returns {String} */ getJSON() { @@ -783,8 +789,8 @@ class Covenant extends bio.Struct { /** * Inject properties from json object. - * @param {String} json - * @returns {Covenant} + * @param {CovenantJSON} json + * @returns {this} */ fromJSON(json) { @@ -804,8 +810,8 @@ class Covenant extends bio.Struct { /** * Inject properties from buffer reader. - * @param {BufferReader} br - * @returns {Covenant} + * @param {bio.BufferReader} br + * @returns {this} */ read(br) { @@ -825,7 +831,7 @@ class Covenant extends bio.Struct { /** * Inject items from string. * @param {String|String[]} items - * @returns {Covenant} + * @returns {this} */ fromString(items) { diff --git a/lib/primitives/headers.js b/lib/primitives/headers.js index 1a6c94952..1733eef7d 100644 --- a/lib/primitives/headers.js +++ b/lib/primitives/headers.js @@ -9,6 +9,15 @@ const util = require('../utils/util'); const AbstractBlock = require('./abstractblock'); +/** @typedef {import('bufio').BufferReader} BufferReader */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('../types').NetworkType} NetworkType */ +/** @typedef {import('../protocol/network')} Network */ +/** @typedef {import('../blockchain/chainentry')} ChainEntry */ +/** @typedef {import('../coins/coinview')} CoinView */ +/** @typedef {import('./block')} Block */ +/** @typedef {import('./merkleblock')} MerkleBlock */ + /** * Headers * Represents block headers obtained @@ -21,7 +30,7 @@ class Headers extends AbstractBlock { /** * Create headers. * @constructor - * @param {Object} options + * @param {Object} [options] */ constructor(options) { @@ -52,7 +61,8 @@ class Headers extends AbstractBlock { /** * Serialize the headers to a buffer writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -62,8 +72,7 @@ class Headers extends AbstractBlock { /** * Inject properties from buffer reader. - * @private - * @param {Buffer} data + * @param {BufferReader} br */ read(br) { @@ -128,9 +137,9 @@ class Headers extends AbstractBlock { /** * Convert the block to an object suitable * for JSON serialization. - * @param {Network} network - * @param {CoinView} view - * @param {Number} height + * @param {(NetworkType|Network)?} [network] + * @param {CoinView} [view] + * @param {Number} [height] * @returns {Object} */ @@ -154,7 +163,6 @@ class Headers extends AbstractBlock { /** * Inject properties from json object. - * @private * @param {Object} json */ @@ -166,8 +174,8 @@ class Headers extends AbstractBlock { /** * Inspect the headers and return a more * user-friendly representation of the data. - * @param {CoinView} view - * @param {Number} height + * @param {CoinView} [view] + * @param {Number} [height] * @returns {Object} */ diff --git a/lib/primitives/input.js b/lib/primitives/input.js index e920cfe1d..6fce81a39 100644 --- a/lib/primitives/input.js +++ b/lib/primitives/input.js @@ -12,6 +12,16 @@ const Network = require('../protocol/network'); const Witness = require('../script/witness'); const Outpoint = require('./outpoint'); +/** @typedef {import('../types').NetworkType} NetworkType */ +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('./tx')} TX */ +/** @typedef {import('./coin')} Coin */ +/** @typedef {import('./address')} Address */ +/** @typedef {import('../wallet/path')} Path */ + +/** @typedef {ReturnType} InputJSON */ + /** * Input * Represents a transaction input. @@ -26,7 +36,7 @@ class Input extends bio.Struct { /** * Create transaction input. * @constructor - * @param {Object} options + * @param {Object?} [options] */ constructor(options) { @@ -42,7 +52,6 @@ class Input extends bio.Struct { /** * Inject properties from options object. - * @private * @param {Object} options */ @@ -65,7 +74,8 @@ class Input extends bio.Struct { /** * Clone the input. - * @returns {Input} + * @param {this} input + * @returns {this} */ inject(input) { @@ -101,7 +111,7 @@ class Input extends bio.Struct { * Get the previous output script's address. Will "guess" * based on the input script and/or witness if coin * is not available. - * @param {Coin?} coin + * @param {Coin?} [coin] * @returns {Address?} addr */ @@ -117,8 +127,8 @@ class Input extends bio.Struct { /** * Get the address hash. - * @param {Coin?} coin - * @returns {Hash} hash + * @param {Coin?} [coin] + * @returns {Hash?} hash */ getHash(coin) { @@ -167,10 +177,9 @@ class Input extends bio.Struct { /** * Convert the input to an object suitable * for JSON serialization. - * @param {Network} network - * @param {Coin} coin - * @param {Path} path - * @returns {Object} + * @param {NetworkType|Network} [network] + * @param {Coin} [coin] + * @param {Path} [path] */ getJSON(network, coin, path) { @@ -195,8 +204,8 @@ class Input extends bio.Struct { /** * Inject properties from a JSON object. - * @private - * @param {Object} json + * @param {InputJSON} json + * @returns {this} */ fromJSON(json) { @@ -220,7 +229,8 @@ class Input extends bio.Struct { /** * Write the input to a buffer writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -231,8 +241,8 @@ class Input extends bio.Struct { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br + * @returns {this} */ read(br) { @@ -243,8 +253,8 @@ class Input extends bio.Struct { /** * Inject properties from outpoint. - * @private * @param {Outpoint} outpoint + * @returns {this} */ fromOutpoint(outpoint) { @@ -257,7 +267,7 @@ class Input extends bio.Struct { /** * Instantiate input from outpoint. - * @param {Outpoint} + * @param {Outpoint} outpoint * @returns {Input} */ @@ -281,7 +291,7 @@ class Input extends bio.Struct { /** * Instantiate input from coin. - * @param {Coin} + * @param {Coin} coin * @returns {Input} */ @@ -291,7 +301,6 @@ class Input extends bio.Struct { /** * Inject properties from transaction. - * @private * @param {TX} tx * @param {Number} index */ diff --git a/lib/primitives/invitem.js b/lib/primitives/invitem.js index 13b19d5b6..e4aeac3ba 100644 --- a/lib/primitives/invitem.js +++ b/lib/primitives/invitem.js @@ -8,6 +8,9 @@ const bio = require('bufio'); +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ + /** * Inv Item * @alias module:primitives.InvItem @@ -20,7 +23,7 @@ class InvItem extends bio.Struct { /** * Create an inv item. * @constructor - * @param {Number} type + * @param {InvItem.types} type * @param {Hash} hash */ @@ -32,7 +35,7 @@ class InvItem extends bio.Struct { /** * Write inv item to buffer writer. - * @param {BufferWriter} bw + * @returns {Number} */ getSize() { @@ -41,19 +44,20 @@ class InvItem extends bio.Struct { /** * Write inv item to buffer writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { bw.writeU32(this.type); bw.writeHash(this.hash); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br + * @returns {this} */ read(br) { diff --git a/lib/primitives/keyring.js b/lib/primitives/keyring.js index 8b9909a21..902015b8d 100644 --- a/lib/primitives/keyring.js +++ b/lib/primitives/keyring.js @@ -17,6 +17,12 @@ const Address = require('./address'); const Output = require('./output'); const secp256k1 = require('bcrypto/lib/secp256k1'); +/** @typedef {import('../types').NetworkType} NetworkType */ +/** @typedef {import('../types').Base58String} Base58String */ +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('./tx')} TX */ + /* * Constants */ @@ -33,19 +39,25 @@ class KeyRing extends bio.Struct { /** * Create a key ring. * @constructor - * @param {Object} options + * @param {Object?} [options] */ constructor(options) { super(); this.publicKey = ZERO_KEY; + /** @type {Buffer?} */ this.privateKey = null; + /** @type {Script?} */ this.script = null; + /** @type {Hash?} */ this._keyHash = null; + /** @type {Address?} */ this._keyAddress = null; + /** @type {Hash?} */ this._scriptHash = null; + /** @type {Address?} */ this._scriptAddress = null; if (options) @@ -54,7 +66,6 @@ class KeyRing extends bio.Struct { /** * Inject properties from options object. - * @private * @param {Object} options */ @@ -94,7 +105,6 @@ class KeyRing extends bio.Struct { /** * Inject data from private key. - * @private * @param {Buffer} key */ @@ -120,7 +130,6 @@ class KeyRing extends bio.Struct { /** * Inject data from public key. - * @private * @param {Buffer} key */ @@ -134,7 +143,6 @@ class KeyRing extends bio.Struct { /** * Generate a keyring. - * @private * @returns {KeyRing} */ @@ -158,28 +166,27 @@ class KeyRing extends bio.Struct { * @returns {KeyRing} */ - static fromPublic(key) { - return new this().fromPublic(key); + static fromPublic(publicKey) { + return new this().fromPublic(publicKey); } /** * Inject data from public key. - * @private - * @param {Buffer} privateKey + * @param {Buffer} key */ fromKey(key) { assert(Buffer.isBuffer(key), 'Key must be a buffer.'); if (key.length === 32) - return this.fromPrivate(key, true); + return this.fromPrivate(key); return this.fromPublic(key); } /** * Instantiate keyring from a public key. - * @param {Buffer} publicKey + * @param {Buffer} key * @returns {KeyRing} */ @@ -255,9 +262,8 @@ class KeyRing extends bio.Struct { /** * Inject properties from serialized secret. - * @private - * @param {Base58String} secret - * @param {(Network|NetworkType)?} network + * @param {Base58String} data + * @param {(Network|NetworkType)?} [network] */ fromSecret(data, network) { @@ -277,7 +283,7 @@ class KeyRing extends bio.Struct { /** * Instantiate a keyring from a serialized secret. - * @param {Base58String} secret + * @param {Base58String} data * @param {(Network|NetworkType)?} network * @returns {KeyRing} */ @@ -424,7 +430,7 @@ class KeyRing extends bio.Struct { /** * Check whether transaction output belongs to this address. * @param {TX|Output} tx - Transaction or Output. - * @param {Number?} index - Output index. + * @param {Number?} [index] - Output index. * @returns {Boolean} */ @@ -499,6 +505,7 @@ class KeyRing extends bio.Struct { /** * Convert an KeyRing to a more json-friendly object. + * @param {(NetworkType|Network)?} [network] * @returns {Object} */ @@ -512,7 +519,6 @@ class KeyRing extends bio.Struct { /** * Inject properties from json object. - * @private * @param {Object} json */ @@ -524,7 +530,7 @@ class KeyRing extends bio.Struct { this.publicKey = Buffer.from(json.publicKey, 'hex'); if (json.script) - this.script = Buffer.from(json.script, 'hex'); + this.script = Script.fromHex(json.script); return this; } @@ -552,7 +558,8 @@ class KeyRing extends bio.Struct { /** * Write the keyring to a buffer writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -574,8 +581,7 @@ class KeyRing extends bio.Struct { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { diff --git a/lib/primitives/memblock.js b/lib/primitives/memblock.js index c27805c37..24d519fcd 100644 --- a/lib/primitives/memblock.js +++ b/lib/primitives/memblock.js @@ -16,6 +16,8 @@ const Output = require('./output'); const consensus = require('../protocol/consensus'); const DUMMY = Buffer.alloc(0); +/** @typedef {import('../types').BufioWriter} BufioWriter */ + /** * Mem Block * A block object which is essentially a "placeholder" @@ -177,8 +179,7 @@ class MemBlock extends AbstractBlock { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -193,7 +194,6 @@ class MemBlock extends AbstractBlock { /** * Inject properties from serialized data. - * @private * @param {Buffer} data */ @@ -204,7 +204,8 @@ class MemBlock extends AbstractBlock { /** * Return serialized block data. - * @returns {Buffer} + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { diff --git a/lib/primitives/merkleblock.js b/lib/primitives/merkleblock.js index 636469b1d..e1ff939a1 100644 --- a/lib/primitives/merkleblock.js +++ b/lib/primitives/merkleblock.js @@ -18,6 +18,14 @@ const Headers = require('./headers'); const DUMMY = Buffer.from([0]); const {encoding} = bio; +/** @typedef {import('@handshake-org/bfilter').BloomFilter} BloomFilter */ +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('../coins/coinview')} CoinView */ +/** @typedef {import('../protocol/network')} Network */ +/** @typedef {import('./block')} Block */ +/** @typedef {import('./tx')} TX */ + /** * Merkle Block * Represents a merkle (filtered) block. @@ -35,7 +43,9 @@ class MerkleBlock extends AbstractBlock { constructor(options) { super(); + /** @type {TX[]} */ this.txs = []; + /** @type {Hash[]} */ this.hashes = []; this.flags = DUMMY; @@ -48,7 +58,6 @@ class MerkleBlock extends AbstractBlock { /** * Inject properties from options object. - * @private * @param {Object} options */ @@ -82,7 +91,7 @@ class MerkleBlock extends AbstractBlock { /** * Clear any cached values. - * @param {Boolean?} all - Clear transactions. + * @param {Boolean?} [all] - Clear transactions. */ refresh(all) { @@ -126,7 +135,6 @@ class MerkleBlock extends AbstractBlock { /** * Verify the partial merkletree. - * @private * @returns {Boolean} */ @@ -275,8 +283,8 @@ class MerkleBlock extends AbstractBlock { /** * Inspect the block and return a more * user-friendly representation of the data. - * @param {CoinView} view - * @param {Number} height + * @param {CoinView} [view] + * @param {Number} [height] * @returns {Object} */ @@ -324,7 +332,8 @@ class MerkleBlock extends AbstractBlock { /** * Write the merkleblock to a buffer writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -344,8 +353,7 @@ class MerkleBlock extends AbstractBlock { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -366,9 +374,9 @@ class MerkleBlock extends AbstractBlock { /** * Convert the block to an object suitable * for JSON serialization. - * @param {Network} network - * @param {CoinView} view - * @param {Number} height + * @param {Network} [network] + * @param {CoinView} [view] + * @param {Number} [height] * @returns {Object} */ @@ -397,7 +405,6 @@ class MerkleBlock extends AbstractBlock { /** * Inject properties from json object. - * @private * @param {Object} json */ @@ -424,7 +431,7 @@ class MerkleBlock extends AbstractBlock { * it through a filter first. This will build the partial * merkle tree. * @param {Block} block - * @param {Bloom} filter + * @param {BloomFilter} filter * @returns {MerkleBlock} */ diff --git a/lib/primitives/mtx.js b/lib/primitives/mtx.js index 2cddb79ea..cfea27a89 100644 --- a/lib/primitives/mtx.js +++ b/lib/primitives/mtx.js @@ -27,6 +27,14 @@ const rules = require('../covenants/rules'); const util = require('../utils/util'); const {types} = rules; +/** @typedef {import('../types').SighashType} SighashType */ +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').Amount} AmountValue */ +/** @typedef {import('../types').VerifyFlags} VerifyFlags */ +/** @typedef {import('../protocol/network')} Network */ +/** @typedef {import('../workers/workerpool')} WorkerPool */ +/** @typedef {import('./keyring')} KeyRing */ + /** * MTX * A mutable transaction object. @@ -41,7 +49,7 @@ class MTX extends TX { * Create a mutable transaction. * @alias module:primitives.MTX * @constructor - * @param {Object} options + * @param {Object?} [options] */ constructor(options) { @@ -57,7 +65,6 @@ class MTX extends TX { /** * Inject properties from options object. - * @private * @param {Object} options */ @@ -102,7 +109,8 @@ class MTX extends TX { /** * Clone the transaction. Note that * this will not carry over the view. - * @returns {MTX} + * @param {this} mtx + * @returns {this} */ inject(mtx) { @@ -197,7 +205,7 @@ class MTX extends TX { /** * Add an output. * @param {Address|Output|Object} addr - Address or output options. - * @param {Amount?} value + * @param {AmountValue?} [value] * @returns {Output} * * @example @@ -221,8 +229,7 @@ class MTX extends TX { /** * Verify all transaction inputs. - * @param {VerifyFlags} [flags=STANDARD_VERIFY_FLAGS] - * @returns {Boolean} Whether the inputs are valid. + * @param {VerifyFlags?} [flags=STANDARD_VERIFY_FLAGS] * @throws {ScriptError} on invalid inputs */ @@ -234,7 +241,7 @@ class MTX extends TX { * Verify the transaction inputs on the worker pool * (if workers are enabled). * @param {VerifyFlags?} [flags=STANDARD_VERIFY_FLAGS] - * @param {WorkerPool?} pool + * @param {WorkerPool?} [pool] * @returns {Promise} */ @@ -244,7 +251,7 @@ class MTX extends TX { /** * Verify all transaction inputs. - * @param {VerifyFlags} [flags=STANDARD_VERIFY_FLAGS] + * @param {VerifyFlags?} [flags=STANDARD_VERIFY_FLAGS] * @returns {Boolean} Whether the inputs are valid. */ @@ -263,7 +270,7 @@ class MTX extends TX { * Verify the transaction inputs on the worker pool * (if workers are enabled). * @param {VerifyFlags?} [flags=STANDARD_VERIFY_FLAGS] - * @param {WorkerPool?} pool + * @param {WorkerPool?} [pool] * @returns {Promise} */ @@ -280,7 +287,7 @@ class MTX extends TX { /** * Calculate the fee for the transaction. - * @returns {Amount} fee (zero if not all coins are available). + * @returns {AmountValue} fee (zero if not all coins are available). */ getFee() { @@ -289,7 +296,7 @@ class MTX extends TX { /** * Calculate the total input value. - * @returns {Amount} value + * @returns {AmountValue} value */ getInputValue() { @@ -344,7 +351,6 @@ class MTX extends TX { /** * Calculate virtual sigop count. - * @param {VerifyFlags?} flags * @returns {Number} sigop count */ @@ -371,6 +377,7 @@ class MTX extends TX { * @param {Number} height - Height at which the * transaction is being spent. In the mempool this is * the chain height plus one at the time it entered the pool. + * @param {Network} network * @returns {Boolean} */ @@ -388,6 +395,7 @@ class MTX extends TX { * @param {Number} height - Height at which the * transaction is being spent. In the mempool this is * the chain height plus one at the time it entered the pool. + * @param {Network} network * @returns {Array} [fee, reason, score] */ @@ -454,8 +462,8 @@ class MTX extends TX { * Build script for a single vector * based on a previous script. * @param {Script} prev - * @param {Buffer} ring - * @return {Boolean} + * @param {KeyRing} ring + * @return {Stack} */ scriptVector(prev, ring) { @@ -516,7 +524,7 @@ class MTX extends TX { * @param {Coin|Output} coin * @param {KeyRing} ring * @param {SighashType?} type - * @param {WorkerPool?} pool + * @param {WorkerPool?} [pool] * @returns {Promise} */ @@ -524,7 +532,7 @@ class MTX extends TX { if (!pool) return this.signInput(index, coin, ring, type); - return await pool.signInput(this, index, coin, ring, type, pool); + return await pool.signInput(this, index, coin, ring, type); } /** @@ -595,7 +603,7 @@ class MTX extends TX { * @param {Stack} vector * @param {Buffer} sig * @param {KeyRing} ring - * @return {Boolean} + * @return {Stack?} */ signVector(prev, vector, sig, ring) { @@ -939,7 +947,7 @@ class MTX extends TX { /** * Estimate maximum possible size. * @param {Function?} estimate - Input script size estimator. - * @returns {Number} + * @returns {Promise} */ async estimateSize(estimate) { @@ -1011,7 +1019,7 @@ class MTX extends TX { * Select necessary coins based on total output value. * @param {Coin[]} coins * @param {Object?} options - * @returns {CoinSelection} + * @returns {Promise} * @throws on not enough funds available. */ @@ -1023,7 +1031,7 @@ class MTX extends TX { /** * Attempt to subtract a fee from a single output. * @param {Number} index - * @param {Amount} fee + * @param {AmountValue} fee */ subtractIndex(index, fee) { @@ -1043,7 +1051,7 @@ class MTX extends TX { /** * Attempt to subtract a fee from all outputs evenly. - * @param {Amount} fee + * @param {AmountValue} fee */ subtractFee(fee) { @@ -1105,7 +1113,7 @@ class MTX extends TX { * Select coins and fill the inputs. * @param {Coin[]} coins * @param {Object} options - See {@link MTX#selectCoins} options. - * @returns {CoinSelector} + * @returns {Promise} */ async fund(coins, options) { @@ -1163,8 +1171,11 @@ class MTX extends TX { assert(changeOutput.covenant.type === 0); } + /** @type {Input[]} */ const inputs = []; + /** @type {Output[]} */ const outputs = []; + // [Input, Output][] const linked = []; let i = 0; @@ -1216,7 +1227,7 @@ class MTX extends TX { /** * Avoid fee sniping. - * @param {Number} - Current chain height. + * @param {Number} height - Current chain height. * @see bitcoin/src/wallet/wallet.cpp */ @@ -1236,7 +1247,7 @@ class MTX extends TX { /** * Set locktime and sequences appropriately. * @param {Number} locktime - * @param {Boolean?} seconds + * @param {Boolean?} [seconds] */ setLocktime(locktime, seconds) { @@ -1598,7 +1609,7 @@ class CoinSelector { /** * Calculate total value required. - * @returns {Amount} + * @returns {AmountValue} */ total() { @@ -1658,7 +1669,7 @@ class CoinSelector { /** * Get the current fee based on a size. * @param {Number} size - * @returns {Amount} + * @returns {AmountValue} */ getFee(size) { @@ -1704,7 +1715,7 @@ class CoinSelector { /** * Initiate selection from `coins`. * @param {Coin[]} coins - * @returns {CoinSelector} + * @returns {Promise} */ async select(coins) { @@ -1867,8 +1878,8 @@ class FundingError extends Error { * Create a funding error. * @constructor * @param {String} msg - * @param {Amount} available - * @param {Amount} required + * @param {AmountValue} [available] + * @param {AmountValue} [required] */ constructor(msg, available, required) { diff --git a/lib/primitives/outpoint.js b/lib/primitives/outpoint.js index 6932ad6f3..5ae9e401b 100644 --- a/lib/primitives/outpoint.js +++ b/lib/primitives/outpoint.js @@ -11,6 +11,17 @@ const bio = require('bufio'); const consensus = require('../protocol/consensus'); const util = require('../utils/util'); +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').HexHash} HexHash */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('./tx')} TX */ + +/** + * @typedef {Object} OutpointJSON + * @property {HexHash} hash + * @property {Number} index + */ + /** * Outpoint * Represents a COutPoint. @@ -23,8 +34,8 @@ class Outpoint extends bio.Struct { /** * Create an outpoint. * @constructor - * @param {Hash?} hash - * @param {Number?} index + * @param {Hash?} [hash] + * @param {Number?} [index] */ constructor(hash, index) { @@ -43,7 +54,6 @@ class Outpoint extends bio.Struct { /** * Inject properties from options object. - * @private * @param {Object} options */ @@ -58,7 +68,8 @@ class Outpoint extends bio.Struct { /** * Clone the outpoint. - * @returns {Outpoint} + * @param {this} prevout + * @returns {this} */ inject(prevout) { @@ -70,7 +81,7 @@ class Outpoint extends bio.Struct { /** * Test equality against another outpoint. - * @param {Outpoint} prevout + * @param {this} prevout * @returns {Boolean} */ @@ -82,7 +93,7 @@ class Outpoint extends bio.Struct { /** * Compare against another outpoint (BIP69). - * @param {Outpoint} prevout + * @param {this} prevout * @returns {Number} */ @@ -119,7 +130,7 @@ class Outpoint extends bio.Struct { /** * Serialize outpoint to a key * suitable for a hash table. - * @returns {String} + * @returns {Buffer} */ toKey() { @@ -128,8 +139,7 @@ class Outpoint extends bio.Struct { /** * Inject properties from hash table key. - * @private - * @param {String} key + * @param {Buffer} key * @returns {Outpoint} */ @@ -142,7 +152,7 @@ class Outpoint extends bio.Struct { /** * Instantiate outpoint from hash table key. - * @param {String} key + * @param {Buffer} key * @returns {Outpoint} */ @@ -152,7 +162,8 @@ class Outpoint extends bio.Struct { /** * Write outpoint to a buffer writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -172,8 +183,7 @@ class Outpoint extends bio.Struct { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -184,8 +194,7 @@ class Outpoint extends bio.Struct { /** * Inject properties from json object. - * @private - * @params {Object} json + * @param {OutpointJSON} json */ fromJSON(json) { @@ -200,7 +209,7 @@ class Outpoint extends bio.Struct { /** * Convert the outpoint to an object suitable * for JSON serialization. - * @returns {Object} + * @returns {OutpointJSON} */ getJSON() { @@ -241,7 +250,7 @@ class Outpoint extends bio.Struct { * suitable for a hash table. * @param {Hash} hash * @param {Number} index - * @returns {String} + * @returns {Buffer} */ static toKey(hash, index) { diff --git a/lib/primitives/output.js b/lib/primitives/output.js index 152ada178..2c955fe27 100644 --- a/lib/primitives/output.js +++ b/lib/primitives/output.js @@ -16,10 +16,23 @@ const policy = require('../protocol/policy'); const util = require('../utils/util'); const Covenant = require('./covenant'); +/** @typedef {import('../types').Amount} AmountValue */ +/** @typedef {import('../types').Rate} Rate */ +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('./covenant').CovenantJSON} CovenantJSON */ + +/** + * @typedef {Object} OutputJSON + * @property {AmountValue} value + * @property {String} address + * @property {CovenantJSON} covenant + */ + /** * Represents a transaction output. * @alias module:primitives.Output - * @property {Amount} value + * @property {AmountValue} value * @property {Address} address */ @@ -27,7 +40,7 @@ class Output extends bio.Struct { /** * Create an output. * @constructor - * @param {Object?} options + * @param {Object?} [options] */ constructor(options) { @@ -43,7 +56,6 @@ class Output extends bio.Struct { /** * Inject properties from options object. - * @private * @param {Object} options */ @@ -66,9 +78,8 @@ class Output extends bio.Struct { /** * Inject properties from address/value pair. - * @private * @param {Address} address - * @param {Amount} value + * @param {AmountValue} value * @returns {Output} */ @@ -84,7 +95,7 @@ class Output extends bio.Struct { /** * Instantiate output from address/value pair. * @param {Address} address - * @param {Amount} value + * @param {AmountValue} value * @returns {Output} */ @@ -94,7 +105,8 @@ class Output extends bio.Struct { /** * Clone the output. - * @returns {Output} + * @param {this} output + * @returns {this} */ inject(output) { @@ -168,8 +180,8 @@ class Output extends bio.Struct { /** * Convert the output to an object suitable * for JSON serialization. - * @param {Network} network - * @returns {Object} + * @param {Network} [network] + * @returns {OutputJSON} */ getJSON(network) { @@ -185,8 +197,8 @@ class Output extends bio.Struct { /** * Calculate the dust threshold for this * output, based on serialize size and rate. - * @param {Rate?} rate - * @returns {Amount} + * @param {Rate?} [rate] + * @returns {AmountValue} */ getDustThreshold(rate) { @@ -216,7 +228,7 @@ class Output extends bio.Struct { /** * Test whether the output should be considered dust. - * @param {Rate?} rate + * @param {Rate?} [rate] * @returns {Boolean} */ @@ -235,8 +247,7 @@ class Output extends bio.Struct { /** * Inject properties from a JSON object. - * @private - * @param {Object} json + * @param {OutputJSON} json */ fromJSON(json) { @@ -254,7 +265,8 @@ class Output extends bio.Struct { /** * Write the output to a buffer writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -266,8 +278,8 @@ class Output extends bio.Struct { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br + * @returns {this} */ read(br) { diff --git a/lib/primitives/tx.js b/lib/primitives/tx.js index 6a203f7dc..49dca5e86 100644 --- a/lib/primitives/tx.js +++ b/lib/primitives/tx.js @@ -28,7 +28,21 @@ const AirdropProof = require('../primitives/airdropproof'); const {encoding} = bio; const {hashType} = Script; +/** @typedef {import('@handshake-org/bfilter').BloomFilter} BloomFilter */ +/** @typedef {import('../types').SighashType} SighashType */ /** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').Amount} AmountValue */ +/** @typedef {import('../types').Rate} Rate */ +/** @typedef {import('../types').VerifyFlags} VerifyFlags */ +/** @typedef {import('../types').HexHash} HexHash */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('../blockchain/chainentry')} ChainEntry */ +/** @typedef {import('../covenants/ownership').OwnershipProof} OwnershipProof */ +/** @typedef {import('../workers/workerpool')} WorkerPool */ +/** @typedef {import('../coins/coinview')} CoinView */ +/** @typedef {import('./covenant')} Covenant */ +/** @typedef {import('./coin')} Coin */ +/** @typedef {import('./address')} Address */ /** * TX @@ -44,28 +58,38 @@ class TX extends bio.Struct { /** * Create a transaction. * @constructor - * @param {Object?} options + * @param {Object?} [options] */ constructor(options) { super(); this.version = 0; + /** @type {Input[]} */ this.inputs = []; + /** @type {Output[]} */ this.outputs = []; this.locktime = 0; this.mutable = false; + /** @type {Hash?} */ this._hash = null; + /** @type {Hash?} */ this._wdhash = null; + /** @type {Hash?} */ this._whash = null; + /** @type {Buffer?} */ this._raw = null; + /** @type {Sizes?} */ this._sizes = null; + /** @type {Hash?} */ this._hashPrevouts = null; + /** @type {Hash?} */ this._hashSequence = null; + /** @type {Hash?} */ this._hashOutputs = null; if (options) @@ -74,7 +98,6 @@ class TX extends bio.Struct { /** * Inject properties from options object. - * @private * @param {Object} options */ @@ -111,9 +134,8 @@ class TX extends bio.Struct { /** * Inject properties from tx. * Used for cloning. - * @private - * @param {TX} tx - * @returns {TX} + * @param {this} tx + * @returns {this} */ inject(tx) { @@ -261,7 +283,7 @@ class TX extends bio.Struct { * @param {Script} prev - Previous output script or redeem script * (in the case of witnesspubkeyhash, this should be the generated * p2pkh script). - * @param {Amount} value - Previous output value. + * @param {AmountValue} value - Previous output value. * @param {SighashType} type - Sighash type. * @returns {Buffer} Signature hash. */ @@ -381,7 +403,7 @@ class TX extends bio.Struct { * Verify signature. * @param {Number} index * @param {Script} prev - * @param {Amount} value + * @param {AmountValue} value * @param {Buffer} sig * @param {Buffer} key * @returns {Boolean} @@ -403,7 +425,7 @@ class TX extends bio.Struct { * @param {Script} prev - Previous output script or redeem script * (in the case of witnesspubkeyhash, this should be the generated * p2pkh script). - * @param {Amount} value - Previous output value. + * @param {AmountValue} value - Previous output value. * @param {Buffer} key * @param {SighashType} type * @returns {Buffer} Signature in DER format. @@ -473,6 +495,7 @@ class TX extends bio.Struct { continue; } + /** @type {OwnershipProof} */ let proof; try { proof = OwnershipProof.decode(witness.items[0]); @@ -531,7 +554,7 @@ class TX extends bio.Struct { * (if workers are enabled). * @param {CoinView} view * @param {VerifyFlags?} [flags=STANDARD_VERIFY_FLAGS] - * @param {WorkerPool?} pool + * @param {WorkerPool?} [pool] * @returns {Promise} */ @@ -553,7 +576,7 @@ class TX extends bio.Struct { * verified. * @param {Coin|Output} coin - Previous output. * @param {VerifyFlags} [flags=STANDARD_VERIFY_FLAGS] - * @param {WorkerPool?} pool + * @param {WorkerPool?} [pool] * @returns {Promise} */ @@ -614,7 +637,7 @@ class TX extends bio.Struct { * (if workers are enabled). * @param {CoinView} view * @param {VerifyFlags?} [flags=STANDARD_VERIFY_FLAGS] - * @param {WorkerPool?} pool + * @param {WorkerPool?} [pool] * @returns {Promise} */ @@ -635,13 +658,13 @@ class TX extends bio.Struct { * verified. * @param {Coin|Output} coin - Previous output. * @param {VerifyFlags} [flags=STANDARD_VERIFY_FLAGS] - * @param {WorkerPool?} pool + * @param {WorkerPool?} [pool] * @returns {Promise} */ async verifyInputAsync(index, coin, flags, pool) { try { - await this.checkInput(index, coin, flags, pool); + await this.checkInputAsync(index, coin, flags, pool); } catch (e) { if (e.type === 'ScriptError') return false; @@ -663,7 +686,7 @@ class TX extends bio.Struct { /** * Calculate the fee for the transaction. * @param {CoinView} view - * @returns {Amount} fee (zero if not all coins are available). + * @returns {AmountValue} fee (zero if not all coins are available). */ getFee(view) { @@ -676,7 +699,7 @@ class TX extends bio.Struct { /** * Calculate the total input value. * @param {CoinView} view - * @returns {Amount} value + * @returns {AmountValue} value */ getInputValue(view) { @@ -696,7 +719,7 @@ class TX extends bio.Struct { /** * Calculate the total output value. - * @returns {Amount} value + * @returns {AmountValue} value */ getOutputValue() { @@ -1296,6 +1319,7 @@ class TX extends bio.Struct { * @param {Number} height - Height at which the * transaction is being spent. In the mempool this is * the chain height plus one at the time it entered the pool. + * @param {Network} network * @returns {Boolean} */ @@ -1314,6 +1338,7 @@ class TX extends bio.Struct { * @param {Number} height - Height at which the * transaction is being spent. In the mempool this is * the chain height plus one at the time it entered the pool. + * @param {Network} network * @returns {Array} [fee, reason, score] */ @@ -1384,7 +1409,8 @@ class TX extends bio.Struct { * any contextual covenants rules. * @param {CoinView} view * @param {Number} height - * @returns {Boolean} + * @param {Network} network + * @returns {Number} */ verifyCovenants(view, height, network) { @@ -1416,7 +1442,7 @@ class TX extends bio.Struct { * Calculate the transaction priority. * @param {CoinView} view * @param {Number} height - * @param {Number?} size - Size to calculate priority + * @param {Number?} [size] - Size to calculate priority * based on. If not present, virtual size will be used. * @returns {Number} */ @@ -1487,9 +1513,9 @@ class TX extends bio.Struct { * passed this test is most likely relayable * without a fee. * @param {CoinView} view - * @param {Number?} height - If not present, tx + * @param {Number} height - If not present, tx * height or network height will be used. - * @param {Number?} size - If not present, modified + * @param {Number?} [size] - If not present, modified * size will be calculated and used. * @returns {Boolean} */ @@ -1502,10 +1528,10 @@ class TX extends bio.Struct { /** * Calculate minimum fee in order for the transaction * to be relayable (not the constant min relay fee). - * @param {Number?} size - If not present, max size + * @param {Number?} [size] - If not present, max size * estimation will be calculated and used. - * @param {Rate?} rate - Rate of dollarydoo per kB. - * @returns {Amount} fee + * @param {Rate?} [rate] - Rate of dollarydoo per kB. + * @returns {AmountValue} fee */ getMinFee(size, rate) { @@ -1519,10 +1545,10 @@ class TX extends bio.Struct { * Calculate the minimum fee in order for the transaction * to be relayable, but _round to the nearest kilobyte * when taking into account size. - * @param {Number?} size - If not present, max size + * @param {Number?} [size] - If not present, max size * estimation will be calculated and used. - * @param {Rate?} rate - Rate of dollarydoo per kB. - * @returns {Amount} fee + * @param {Rate?} [rate] - Rate of dollarydoo per kB. + * @returns {AmountValue} fee */ getRoundFee(size, rate) { @@ -1536,7 +1562,7 @@ class TX extends bio.Struct { * Calculate the transaction's rate based on size * and fees. Size will be calculated if not present. * @param {CoinView} view - * @param {Number?} size + * @param {Number?} [size] * @returns {Rate} */ @@ -1703,9 +1729,9 @@ class TX extends bio.Struct { /** * Inspect the transaction and return a more * user-friendly representation of the data. - * @param {CoinView} view - * @param {ChainEntry} entry - * @param {Number} index + * @param {CoinView?} [view] + * @param {ChainEntry?} [entry] + * @param {Number?} [index] * @returns {Object} */ @@ -1763,10 +1789,10 @@ class TX extends bio.Struct { /** * Convert the transaction to an object suitable * for JSON serialization. - * @param {Network} network - * @param {CoinView} view - * @param {ChainEntry} entry - * @param {Number} index + * @param {Network} [network] + * @param {CoinView} [view] + * @param {ChainEntry} [entry] + * @param {Number} [index] * @returns {Object} */ @@ -1818,7 +1844,6 @@ class TX extends bio.Struct { /** * Inject properties from a json object. - * @private * @param {Object} json */ @@ -1846,8 +1871,7 @@ class TX extends bio.Struct { /** * Inject properties from serialized * buffer reader (witness serialization). - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -1927,9 +1951,8 @@ class TX extends bio.Struct { /** * Serialize transaction with witness. Calculates the witness * size as it is framing (exposed on return value as `witness`). - * @private - * @param {BufferWriter} bw - * @returns {BufferWriter} + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { diff --git a/lib/primitives/txmeta.js b/lib/primitives/txmeta.js index 2ca1421e2..a2a18e147 100644 --- a/lib/primitives/txmeta.js +++ b/lib/primitives/txmeta.js @@ -11,6 +11,12 @@ const bio = require('bufio'); const util = require('../utils/util'); const TX = require('./tx'); +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('../blockchain/chainentry')} ChainEntry */ +/** @typedef {import('../coins/coinview')} CoinView */ +/** @typedef {import('../protocol/network')} Network */ + /** * TXMeta * An extended transaction object. @@ -21,7 +27,7 @@ class TXMeta extends bio.Struct { /** * Create an extended transaction. * @constructor - * @param {Object?} options + * @param {Object?} [options] */ constructor(options) { @@ -30,6 +36,7 @@ class TXMeta extends bio.Struct { this.tx = new TX(); this.mtime = util.now(); this.height = -1; + /** @type {Hash} */ this.block = null; this.time = 0; this.index = -1; @@ -40,7 +47,6 @@ class TXMeta extends bio.Struct { /** * Inject properties from options object. - * @private * @param {Object} options */ @@ -81,8 +87,9 @@ class TXMeta extends bio.Struct { /** * Inject properties from options object. - * @private - * @param {Object} options + * @param {TX} tx + * @param {ChainEntry} entry + * @param {Number} index */ fromTX(tx, entry, index) { @@ -98,7 +105,9 @@ class TXMeta extends bio.Struct { /** * Instantiate TXMeta from options. - * @param {Object} options + * @param {TX} tx + * @param {ChainEntry} entry + * @param {Number} index * @returns {TXMeta} */ @@ -108,6 +117,7 @@ class TXMeta extends bio.Struct { /** * Inspect the transaction. + * @param {CoinView} view * @returns {Object} */ @@ -123,8 +133,9 @@ class TXMeta extends bio.Struct { /** * Convert the transaction to an object suitable * for JSON serialization. - * @param {Network} network - * @param {CoinView} view + * @param {Network} [network] + * @param {CoinView} [view] + * @param {Number} [chainHeight] * @returns {Object} */ @@ -144,7 +155,6 @@ class TXMeta extends bio.Struct { /** * Inject properties from a json object. - * @private * @param {Object} json */ @@ -193,7 +203,8 @@ class TXMeta extends bio.Struct { * to store transactions in the database. The extended * serialization includes the height, block hash, index, * timestamp, and pending-since time. - * @returns {Buffer} + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -216,8 +227,7 @@ class TXMeta extends bio.Struct { /** * Inject properties from "extended" serialization format. - * @private - * @param {Buffer} data + * @param {bio.BufferReader} br */ read(br) { diff --git a/lib/script/common.js b/lib/script/common.js index 2fdb5fd56..2b003d3d3 100644 --- a/lib/script/common.js +++ b/lib/script/common.js @@ -14,6 +14,9 @@ const assert = require('bsert'); const secp256k1 = require('bcrypto/lib/secp256k1'); const ScriptNum = require('./scriptnum'); +/** @typedef {import('../types').SighashType} SighashType */ +/** @typedef {import('../types').VerifyFlags} VerifyFlags */ + /** * Opcodes by value. * @const {Object} @@ -342,7 +345,7 @@ exports.small = [ /** * Script and locktime flags. See {@link VerifyFlags}. - * @enum {Number} + * @enum {VerifyFlags} */ exports.flags = { diff --git a/lib/script/opcode.js b/lib/script/opcode.js index 9ec15ef42..ab6a8d63b 100644 --- a/lib/script/opcode.js +++ b/lib/script/opcode.js @@ -12,6 +12,9 @@ const ScriptNum = require('./scriptnum'); const common = require('./common'); const opcodes = common.opcodes; +/** @typedef {import('../types').BufioWriter} BufioWriter */ + +/** @type {Opcode[]} */ const opCache = []; let PARSE_ERROR = null; @@ -31,7 +34,7 @@ class Opcode { * Note: this should not be called directly. * @constructor * @param {Number} value - Opcode. - * @param {Buffer?} data - Pushdata buffer. + * @param {Buffer?} [data] - Pushdata buffer. */ constructor(value, data) { @@ -175,8 +178,8 @@ class Opcode { /** * Get string for opcode. - * @param {String?} enc - * @returns {Buffer|null} + * @param {String?} [enc] + * @returns {String|null} */ toString(enc) { @@ -205,8 +208,8 @@ class Opcode { /** * Convert opcode to script number. - * @param {Boolean?} minimal - * @param {Number?} limit + * @param {Boolean?} [minimal] + * @param {Number?} [limit] * @returns {ScriptNum|null} */ @@ -296,7 +299,8 @@ class Opcode { /** * Encode the opcode to a buffer writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -498,7 +502,7 @@ class Opcode { /** * Instantiate an opcode from a ScriptNum. - * @param {ScriptNumber} num + * @param {ScriptNum} num * @returns {Opcode} */ @@ -574,7 +578,7 @@ class Opcode { /** * Instantiate opcode from buffer reader. - * @param {BufferReader} br + * @param {bio.BufferReader} br * @returns {Opcode} */ diff --git a/lib/script/script.js b/lib/script/script.js index 06bad4ccb..6ce9148b6 100644 --- a/lib/script/script.js +++ b/lib/script/script.js @@ -27,6 +27,16 @@ const opcodes = common.opcodes; const scriptTypes = common.types; const {encoding} = bio; +/** @typedef {import('@handshake-org/bfilter').BloomFilter} BloomFilter */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('../types').SighashType} SighashType */ +/** @typedef {import('../types').VerifyFlags} VerifyFlags */ +/** @typedef {import('../types').Amount} AmountValue */ +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('./witness')} Witness */ +/** @typedef {import('../primitives/address')} Address */ +/** @typedef {import('../primitives/tx')} TX */ + /* * Constants */ @@ -46,13 +56,14 @@ class Script extends bio.Struct { /** * Create a script. * @constructor - * @param {Buffer|Array|Object} code + * @param {Object?} [options] */ constructor(options) { super(); this.raw = EMPTY_BUFFER; + /** @type {Opcode[]} */ this.code = []; if (options) @@ -79,8 +90,8 @@ class Script extends bio.Struct { /** * Inject properties from options object. - * @private * @param {Object} options + * @returns {this} */ fromOptions(options) { @@ -111,7 +122,6 @@ class Script extends bio.Struct { /** * Instantiate a value-only iterator. - * @returns {ScriptIterator} */ values() { @@ -120,7 +130,6 @@ class Script extends bio.Struct { /** * Instantiate a key and value iterator. - * @returns {ScriptIterator} */ entries() { @@ -129,7 +138,6 @@ class Script extends bio.Struct { /** * Instantiate a value-only iterator. - * @returns {ScriptIterator} */ [Symbol.iterator]() { @@ -150,9 +158,8 @@ class Script extends bio.Struct { /** * Inject properties from an array of * of buffers and numbers. - * @private - * @param {Array} code - * @returns {Script} + * @param {Opcode[]} code + * @returns {this} */ fromArray(code) { @@ -169,7 +176,7 @@ class Script extends bio.Struct { /** * Instantiate script from an array * of buffers and numbers. - * @param {Array} code + * @param {Opcode[]} code * @returns {Script} */ @@ -199,9 +206,8 @@ class Script extends bio.Struct { /** * Inject data from stack items. - * @private * @param {Buffer[]} items - * @returns {Script} + * @returns {this} */ fromItems(items) { @@ -236,9 +242,8 @@ class Script extends bio.Struct { /** * Inject data from stack. - * @private * @param {Stack} stack - * @returns {Script} + * @returns {this} */ fromStack(stack) { @@ -258,9 +263,8 @@ class Script extends bio.Struct { /** * Inject properties from script. * Used for cloning. - * @private - * @param {Script} script - * @returns {Script} + * @param {this} script + * @returns {this} */ inject(script) { @@ -293,7 +297,7 @@ class Script extends bio.Struct { /** * Clear the script. - * @returns {Script} + * @returns {this} */ clear() { @@ -343,7 +347,6 @@ class Script extends bio.Struct { /** * Re-encode the script internally. Useful if you * changed something manually in the `code` array. - * @returns {Script} */ compile() { @@ -367,7 +370,8 @@ class Script extends bio.Struct { /** * Write the script to a buffer writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -377,8 +381,7 @@ class Script extends bio.Struct { /** * Encode the script to a Buffer. See {@link Script#encode}. - * @param {String} enc - Encoding, either `'hex'` or `null`. - * @returns {Buffer|String} Serialized script. + * @returns {Buffer} Serialized script. */ encode() { @@ -396,7 +399,6 @@ class Script extends bio.Struct { /** * Inject properties from json object. - * @private * @param {String} json */ @@ -408,13 +410,14 @@ class Script extends bio.Struct { /** * Get the script's "subscript" starting at a separator. * @param {Number} index - The last separator to sign/verify beyond. - * @returns {Script} Subscript. + * @returns {this} Subscript. */ getSubscript(index) { if (index === 0) return this.clone(); + /** @type {this} */ const script = new Script(); for (let i = index; i < this.code.length; i++) { @@ -434,7 +437,7 @@ class Script extends bio.Struct { * Remove all OP_CODESEPARATORs if present. This bizarre * behavior is necessary for signing and verification when * code separators are present. - * @returns {Script} Subscript. + * @returns {this}. */ removeSeparators() { @@ -458,6 +461,7 @@ class Script extends bio.Struct { // Uncommon case: someone actually // has a code separator. Go through // and remove them all. + /** @type {this} */ const script = new Script(); for (const op of this.code) { @@ -477,7 +481,7 @@ class Script extends bio.Struct { * @param {Number?} flags - Script standard flags. * @param {TX?} tx - Transaction being verified. * @param {Number?} index - Index of input being verified. - * @param {Amount?} value - Previous output value. + * @param {AmountValue?} value - Previous output value. * @throws {ScriptError} Will be thrown on VERIFY failures. */ @@ -1323,8 +1327,8 @@ class Script extends bio.Struct { /** * Inject properties from a pay-to-pubkey script. - * @private * @param {Buffer} key + * @returns {this} */ fromPubkey(key) { @@ -1435,7 +1439,7 @@ class Script extends bio.Struct { /** * Get the standard script type. - * @returns {ScriptType} + * @returns {common.types} */ getType() { @@ -1655,7 +1659,7 @@ class Script extends bio.Struct { /** * Test the script against a bloom filter. - * @param {Bloom} filter + * @param {BloomFilter} filter * @returns {Boolean} */ @@ -2171,8 +2175,7 @@ class Script extends bio.Struct { /** * Inject properties from bitcoind test string. - * @private - * @param {String} items - Script string. + * @param {String} code - Script string. * @throws Parse error. */ @@ -2238,7 +2241,7 @@ class Script extends bio.Struct { * @param {Address} addr * @param {TX} tx * @param {Number} index - * @param {Amount} value + * @param {AmountValue} value * @param {VerifyFlags} flags * @throws {ScriptError} */ @@ -2304,8 +2307,7 @@ class Script extends bio.Struct { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -2314,8 +2316,8 @@ class Script extends bio.Struct { /** * Inject properties from serialized data. - * @private - * @param {Buffer} + * @param {Buffer} data + * @returns {this} */ decode(data) { diff --git a/lib/script/scripterror.js b/lib/script/scripterror.js index 1ba91ea37..99ef17947 100644 --- a/lib/script/scripterror.js +++ b/lib/script/scripterror.js @@ -6,6 +6,8 @@ 'use strict'; +/** @typedef {import('./opcode')} Opcode */ + /** * Script Error * An error thrown from the scripting system, @@ -23,8 +25,8 @@ class ScriptError extends Error { * Create an error. * @constructor * @param {String} code - Error code. - * @param {Opcode} op - Opcode. - * @param {Number?} ip - Instruction pointer. + * @param {Opcode|String} [op] - Opcode. + * @param {Number?} [ip] - Instruction pointer. */ constructor(code, op, ip) { diff --git a/lib/script/scriptnum.js b/lib/script/scriptnum.js index 2c91dd6cb..b94238607 100644 --- a/lib/script/scriptnum.js +++ b/lib/script/scriptnum.js @@ -29,8 +29,8 @@ class ScriptNum extends I64 { /** * Create a script number. * @constructor - * @param {(Number|String|Buffer|Object)?} num - * @param {(String|Number)?} base + * @param {(Number|String|Buffer|Object)?} [num] + * @param {(String|Number)?} [base] */ constructor(num, base) { @@ -170,8 +170,8 @@ class ScriptNum extends I64 { * Decode and verify script number. * @private * @param {Buffer} data - * @param {Boolean?} minimal - Require minimal encoding. - * @param {Number?} limit - Size limit. + * @param {Boolean?} [minimal] - Require minimal encoding. + * @param {Number?} [limit] - Size limit. * @returns {ScriptNum} */ @@ -223,8 +223,8 @@ class ScriptNum extends I64 { /** * Decode and verify script number. * @param {Buffer} data - * @param {Boolean?} minimal - Require minimal encoding. - * @param {Number?} limit - Size limit. + * @param {Boolean?} [minimal] - Require minimal encoding. + * @param {Number?} [limit] - Size limit. * @returns {ScriptNum} */ diff --git a/lib/script/sigcache.js b/lib/script/sigcache.js index f256cfd2a..2ba0a86eb 100644 --- a/lib/script/sigcache.js +++ b/lib/script/sigcache.js @@ -10,6 +10,8 @@ const assert = require('bsert'); const {BufferMap} = require('buffer-map'); const secp256k1 = require('bcrypto/lib/secp256k1'); +/** @typedef {import('../types').Hash} Hash */ + /** * Signature cache. * @alias module:script.SigCache diff --git a/lib/script/stack.js b/lib/script/stack.js index 06ccf184d..1a27b850c 100644 --- a/lib/script/stack.js +++ b/lib/script/stack.js @@ -23,7 +23,7 @@ class Stack extends bio.Struct { /** * Create a stack. * @constructor - * @param {Buffer[]?} items - Stack items. + * @param {Buffer[]?} [items] - Stack items. */ constructor(items) { @@ -51,7 +51,7 @@ class Stack extends bio.Struct { /** * Instantiate a value-only iterator. - * @returns {StackIterator} + * @returns {IterableIterator} */ [Symbol.iterator]() { @@ -60,7 +60,7 @@ class Stack extends bio.Struct { /** * Instantiate a value-only iterator. - * @returns {StackIterator} + * @returns {IterableIterator} */ values() { @@ -69,7 +69,6 @@ class Stack extends bio.Struct { /** * Instantiate a key and value iterator. - * @returns {StackIterator} */ entries() { @@ -116,7 +115,8 @@ class Stack extends bio.Struct { /** * Clone the stack. - * @returns {Stack} Cloned stack. + * @param {this} stack + * @returns {this} Cloned stack. */ inject(stack) { @@ -196,8 +196,8 @@ class Stack extends bio.Struct { /** * Set stack item at index. * @param {Number} index - * @param {Buffer} value - * @returns {Buffer} + * @param {Buffer} item + * @returns {this} */ set(index, item) { @@ -216,7 +216,7 @@ class Stack extends bio.Struct { * Push item onto stack. * @see Array#push * @param {Buffer} item - * @returns {Number} Stack size. + * @returns {this} */ push(item) { @@ -229,7 +229,7 @@ class Stack extends bio.Struct { * Unshift item from stack. * @see Array#unshift * @param {Buffer} item - * @returns {Number} + * @returns {this} */ unshift(item) { @@ -242,7 +242,7 @@ class Stack extends bio.Struct { * Insert an item. * @param {Number} index * @param {Buffer} item - * @returns {Buffer} + * @returns {this} */ insert(index, item) { @@ -271,7 +271,7 @@ class Stack extends bio.Struct { if (end < 0) end = this.items.length + end; - this.items.splice(start, end - start); + return this.items.splice(start, end - start); } /** diff --git a/lib/script/witness.js b/lib/script/witness.js index 768f148b1..cff666bc3 100644 --- a/lib/script/witness.js +++ b/lib/script/witness.js @@ -17,6 +17,17 @@ const Stack = require('./stack'); const {encoding} = bio; const scriptTypes = common.types; +/** @typedef {import('@handshake-org/bfilter').BloomFilter} BloomFilter */ +/** @typedef {import('../types').ScriptType} ScriptType */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ + +/** + * @typedef {Object} WitnessOptions + * @property {Buffer[]} items + * @property {Script?} redeem + * @property {Number} length + */ + /** * Witness * Refers to the witness vector of @@ -33,11 +44,8 @@ class Witness extends Stack { * Create a witness. * @alias module:script.Witness * @constructor - * @param {Buffer[]|Object} items - Array of + * @param {Buffer[]|WitnessOptions} [options] - Array of * stack items. - * @property {Buffer[]} items - * @property {Script?} redeem - * @property {Number} length */ constructor(options) { @@ -49,8 +57,8 @@ class Witness extends Stack { /** * Inject properties from options object. - * @private - * @param {Object} options + * @param {Buffer[]|WitnessOptions} options + * @returns {this} */ fromOptions(options) { @@ -138,7 +146,6 @@ class Witness extends Stack { /** * Inject properties from a stack. - * @private * @param {Stack} stack */ @@ -168,9 +175,8 @@ class Witness extends Stack { /** * Inject properties from witness. * Used for cloning. - * @private - * @param {Witness} witness - * @returns {Witness} + * @param {this} witness + * @returns {this} */ inject(witness) { @@ -303,7 +309,7 @@ class Witness extends Stack { /** * Test the witness against a bloom filter. - * @param {Bloom} filter + * @param {BloomFilter} filter * @returns {Boolean} */ @@ -321,7 +327,7 @@ class Witness extends Stack { /** * Grab and deserialize the redeem script from the witness. - * @returns {Script} Redeem script. + * @returns {Script?} Redeem script. */ getRedeem() { @@ -378,7 +384,8 @@ class Witness extends Stack { /** * Write witness to a buffer writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -403,7 +410,7 @@ class Witness extends Stack { /** * Convert witness to a hex string. - * @returns {String} + * @returns {String[]} */ getJSON() { @@ -417,8 +424,7 @@ class Witness extends Stack { /** * Inject properties from json object. - * @private - * @param {String} json + * @param {String[]} json */ fromJSON(json) { @@ -434,8 +440,7 @@ class Witness extends Stack { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -452,7 +457,6 @@ class Witness extends Stack { /** * Inject items from string. - * @private * @param {String|String[]} items */ diff --git a/lib/types.js b/lib/types.js index 9f4458928..f8ef93123 100644 --- a/lib/types.js +++ b/lib/types.js @@ -71,7 +71,7 @@ /** * Signature hash type. One of `all`, `single`, `none`, or * one of {@link constants.hashType}. - * @typedef {String|Number} SighashType + * @typedef {Number} SighashType * @global */ @@ -116,4 +116,17 @@ * @global */ +/** + * Raw block data. + * @typedef {Buffer} RawBlock + * @global + */ + +/** @typedef {import('bufio').StaticWriter} StaticWriter */ +/** @typedef {import('bufio').BufferWriter} BufferWriter */ + +/** + * @typedef {StaticWriter|BufferWriter} BufioWriter + */ + module.exports = {}; diff --git a/lib/wallet/path.js b/lib/wallet/path.js index f3e9f9195..6b498945a 100644 --- a/lib/wallet/path.js +++ b/lib/wallet/path.js @@ -12,6 +12,9 @@ const Address = require('../primitives/address'); const Network = require('../protocol/network'); const {encoding} = bio; +/** @typedef {import('../types').NetworkType} NetworkType */ +/** @typedef {import('./account')} Account */ + /** * Path * @alias module:wallet.Path @@ -51,9 +54,8 @@ class Path extends bio.Struct { /** * Instantiate path from options object. - * @private * @param {Object} options - * @returns {Path} + * @returns {this} */ fromOptions(options) { @@ -75,7 +77,8 @@ class Path extends bio.Struct { /** * Clone the path object. - * @returns {Path} + * @param {this} path + * @returns {this} */ inject(path) { @@ -97,8 +100,8 @@ class Path extends bio.Struct { /** * Inject properties from serialized data. - * @private - * @param {Buffer} data + * @param {bio.BufferReader} br + * @returns {this} */ read(br) { @@ -151,7 +154,8 @@ class Path extends bio.Struct { /** * Serialize path. - * @returns {Buffer} + * @param {bio.BufferWriter} bw + * @returns {bio.BufferWriter} */ write(bw) { @@ -213,7 +217,7 @@ class Path extends bio.Struct { /** * Convert path object to string derivation path. - * @param {(String|Network)?} network - Network type. + * @param {(NetworkType|Network)?} [network] - Network type. * @returns {String} */ diff --git a/lib/workers/workerpool.js b/lib/workers/workerpool.js index 474a0602c..c252b308e 100644 --- a/lib/workers/workerpool.js +++ b/lib/workers/workerpool.js @@ -234,7 +234,7 @@ class WorkerPool extends EventEmitter { * Execute the tx signing job (default timeout). * @method * @param {MTX} tx - * @param {KeyRing[]} ring + * @param {KeyRing|KeyRing[]} ring * @param {SighashType} type * @returns {Promise} */ From 685a2202ada7f24775de0b24650a755f7fa48013 Mon Sep 17 00:00:00 2001 From: Nodari Chkuaselidze Date: Sat, 28 Sep 2024 18:44:27 +0400 Subject: [PATCH 4/6] types: update net packets. --- lib/blockchain/chaindb.js | 2 +- lib/net/bip152.js | 45 +++++------- lib/net/packets.js | 151 ++++++++++++++++++-------------------- lib/net/peer.js | 3 + 4 files changed, 94 insertions(+), 107 deletions(-) diff --git a/lib/blockchain/chaindb.js b/lib/blockchain/chaindb.js index 98f012552..278f007c1 100644 --- a/lib/blockchain/chaindb.js +++ b/lib/blockchain/chaindb.js @@ -1178,7 +1178,7 @@ class ChainDB { /** * Get a coin (unspents only). * @param {Outpoint} prevout - * @returns {Promise} - Returns {@link CoinEntry}. + * @returns {Promise} - Returns {@link CoinEntry}. */ async readCoin(prevout) { diff --git a/lib/net/bip152.js b/lib/net/bip152.js index 3cd88c0cf..d6fb3474b 100644 --- a/lib/net/bip152.js +++ b/lib/net/bip152.js @@ -22,6 +22,10 @@ const Block = require('../primitives/block'); const common = require('./common'); const {encoding} = bio; +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('../mempool/mempool')} Mempool */ + const { MAX_BLOCK_SIZE, HEADER_SIZE @@ -45,7 +49,7 @@ class CompactBlock extends AbstractBlock { /** * Create a compact block. * @constructor - * @param {Object?} options + * @param {Object?} [options] */ constructor(options) { @@ -68,7 +72,6 @@ class CompactBlock extends AbstractBlock { /** * Inject properties from options object. - * @private * @param {Object} options */ @@ -111,8 +114,7 @@ class CompactBlock extends AbstractBlock { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -173,8 +175,7 @@ class CompactBlock extends AbstractBlock { /** * Serialize block to buffer writer. - * @private - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { @@ -308,7 +309,6 @@ class CompactBlock extends AbstractBlock { /** * Initialize compact block and short id map. - * @private */ init() { @@ -389,7 +389,6 @@ class CompactBlock extends AbstractBlock { /** * Inject properties from block. - * @private * @param {Block} block * @param {Buffer?} nonce * @returns {CompactBlock} @@ -462,7 +461,7 @@ class TXRequest extends bio.Struct { /** * TX Request * @constructor - * @param {Object?} options + * @param {Object?} [options] */ constructor(options) { @@ -477,9 +476,8 @@ class TXRequest extends bio.Struct { /** * Inject properties from options. - * @private * @param {Object} options - * @returns {TXRequest} + * @returns {this} */ fromOptions(options) { @@ -493,7 +491,6 @@ class TXRequest extends bio.Struct { /** * Inject properties from compact block. - * @private * @param {CompactBlock} block * @returns {TXRequest} */ @@ -521,9 +518,8 @@ class TXRequest extends bio.Struct { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br - * @returns {TXRequest} + * @param {bio.BufferReader} br + * @returns {this} */ read(br) { @@ -575,7 +571,8 @@ class TXRequest extends bio.Struct { /** * Write serialized request to buffer writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -608,7 +605,7 @@ class TXResponse extends bio.Struct { /** * Create a tx response. * @constructor - * @param {Object?} options + * @param {Object?} [options] */ constructor(options) { @@ -623,9 +620,8 @@ class TXResponse extends bio.Struct { /** * Inject properties from options. - * @private * @param {Object} options - * @returns {TXResponse} + * @returns {this} */ fromOptions(options) { @@ -639,9 +635,8 @@ class TXResponse extends bio.Struct { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br - * @returns {TXResponse} + * @param {bio.BufferReader} br + * @returns {this} */ read(br) { @@ -657,8 +652,8 @@ class TXResponse extends bio.Struct { /** * Inject properties from block. - * @private * @param {Block} block + * @param {TXRequest} req * @returns {TXResponse} */ @@ -678,6 +673,7 @@ class TXResponse extends bio.Struct { /** * Instantiate response from block. * @param {Block} block + * @param {TXRequest} req * @returns {TXResponse} */ @@ -704,8 +700,7 @@ class TXResponse extends bio.Struct { /** * Write serialized response to buffer writer. - * @private - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { diff --git a/lib/net/packets.js b/lib/net/packets.js index 6a38a8783..0876e09fa 100644 --- a/lib/net/packets.js +++ b/lib/net/packets.js @@ -31,7 +31,10 @@ const {encoding} = bio; const DUMMY = Buffer.alloc(0); /** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').Rate} Rate */ /** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('../protocol/errors').VerifyError} VerifyError */ +/** @typedef {import('../primitives/block')} Block */ /** * Packet types. @@ -804,7 +807,7 @@ class BlockPacket extends Packet { /** * Serialize block packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { @@ -813,8 +816,7 @@ class BlockPacket extends Packet { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -855,7 +857,7 @@ class TXPacket extends Packet { /** * Serialize tx packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { @@ -864,8 +866,7 @@ class TXPacket extends Packet { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -881,13 +882,14 @@ class TXPacket extends Packet { * (see {@link RejectPacket.codes}). * @property {String?} msg - Message. * @property {String?} reason - Reason. - * @property {(Hash|Buffer)?} data - Transaction or block hash. + * @property {(Hash|Buffer)?} hash - Transaction or block hash. */ class RejectPacket extends Packet { /** * Create reject packet. * @constructor + * @param {Object} [options] */ constructor(options) { @@ -898,6 +900,7 @@ class RejectPacket extends Packet { this.message = 0; this.code = RejectPacket.codes.INVALID; this.reason = ''; + /** @type {Hash?} */ this.hash = null; if (options) @@ -906,7 +909,6 @@ class RejectPacket extends Packet { /** * Inject properties from options object. - * @private * @param {Object} options */ @@ -970,7 +972,7 @@ class RejectPacket extends Packet { /** * Serialize reject packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { @@ -982,13 +984,12 @@ class RejectPacket extends Packet { if (this.hash) bw.writeHash(this.hash); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -1013,11 +1014,10 @@ class RejectPacket extends Packet { /** * Inject properties from reason message and object. - * @private - * @param {Number} code + * @param {(String|Number)?} code * @param {String} reason - * @param {String?} msg - * @param {Hash?} hash + * @param {Number?} [msg] + * @param {Hash?} [hash] */ fromReason(code, reason, msg, hash) { @@ -1045,10 +1045,10 @@ class RejectPacket extends Packet { /** * Instantiate reject packet from reason message. - * @param {Number} code + * @param {(String|Number)?} code * @param {String} reason - * @param {String?} msg - * @param {Hash?} hash + * @param {Number?} [msg] + * @param {Hash?} [hash] * @returns {RejectPacket} */ @@ -1059,7 +1059,7 @@ class RejectPacket extends Packet { /** * Instantiate reject packet from verify error. * @param {VerifyError} err - * @param {(TX|Block)?} obj + * @param {(TX|Block)?} [obj] * @returns {RejectPacket} */ @@ -1177,7 +1177,7 @@ class FilterLoadPacket extends Packet { /** * Serialize filterload packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { @@ -1186,8 +1186,7 @@ class FilterLoadPacket extends Packet { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -1237,18 +1236,17 @@ class FilterAddPacket extends Packet { /** * Serialize filteradd packet to writer. - * @returns {BufferWriter} bw + * @returns {BufioWriter} bw */ write(bw) { bw.writeVarBytes(this.data); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -1306,7 +1304,7 @@ class MerkleBlockPacket extends Packet { /** * Serialize merkleblock packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { @@ -1315,8 +1313,7 @@ class MerkleBlockPacket extends Packet { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -1357,18 +1354,17 @@ class FeeFilterPacket extends Packet { /** * Serialize feefilter packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { bw.writeI64(this.rate); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -1412,19 +1408,18 @@ class SendCmpctPacket extends Packet { /** * Serialize sendcmpct packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { bw.writeU8(this.mode); bw.writeU64(this.version); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -1452,12 +1447,13 @@ class CmpctBlockPacket extends Packet { this.type = exports.types.CMPCTBLOCK; + /** @type {Block|bip152.CompactBlock} */ this.block = block || new bip152.CompactBlock(); } /** * Serialize cmpctblock packet. - * @returns {Buffer} + * @returns {Number} */ getSize() { @@ -1466,7 +1462,7 @@ class CmpctBlockPacket extends Packet { /** * Serialize cmpctblock packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { @@ -1475,8 +1471,7 @@ class CmpctBlockPacket extends Packet { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -1488,14 +1483,14 @@ class CmpctBlockPacket extends Packet { /** * GetBlockTxn Packet * @extends Packet - * @property {TXRequest} request + * @property {bip152.TXRequest} request */ class GetBlockTxnPacket extends Packet { /** * Create a `getblocktxn` packet. * @constructor - * @param {TXRequest?} request + * @param {bip152.TXRequest?} [request] */ constructor(request) { @@ -1517,7 +1512,7 @@ class GetBlockTxnPacket extends Packet { /** * Serialize getblocktxn packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { @@ -1526,8 +1521,7 @@ class GetBlockTxnPacket extends Packet { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -1539,14 +1533,14 @@ class GetBlockTxnPacket extends Packet { /** * BlockTxn Packet * @extends Packet - * @property {TXResponse} response + * @property {bip152.TXResponse} response */ class BlockTxnPacket extends Packet { /** * Create a `blocktxn` packet. * @constructor - * @param {TXResponse?} response + * @param {bip152.TXResponse?} [response] */ constructor(response) { @@ -1568,7 +1562,7 @@ class BlockTxnPacket extends Packet { /** * Serialize blocktxn packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { @@ -1577,8 +1571,7 @@ class BlockTxnPacket extends Packet { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -1598,8 +1591,8 @@ class GetProofPacket extends Packet { /** * Create a `getproof` packet. * @constructor - * @param {Buffer?} root - * @param {Buffer?} key + * @param {Buffer?} [root] + * @param {Buffer?} [key] */ constructor(root, key) { @@ -1621,19 +1614,18 @@ class GetProofPacket extends Packet { /** * Serialize getproof packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { bw.writeHash(this.root); bw.writeBytes(this.key); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -1653,9 +1645,9 @@ class ProofPacket extends Packet { /** * Create a `proof` packet. * @constructor - * @param {Buffer} root - * @param {Buffer} key - * @param {UrkelProof} proof + * @param {Buffer} [root] + * @param {Buffer} [key] + * @param {UrkelProof} [proof] */ constructor(root, key, proof) { @@ -1680,20 +1672,19 @@ class ProofPacket extends Packet { /** * Serialize proof packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { bw.writeHash(this.root); bw.writeBytes(this.key); this.proof.writeBW(bw, blake2b, 256); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -1713,7 +1704,7 @@ class ClaimPacket extends Packet { /** * Create a `proof` packet. * @constructor - * @param {Claim?} claim + * @param {Claim?} [claim] */ constructor(claim) { @@ -1734,18 +1725,17 @@ class ClaimPacket extends Packet { /** * Serialize proof packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { this.claim.write(bw); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -1763,7 +1753,7 @@ class AirdropPacket extends Packet { /** * Create a `proof` packet. * @constructor - * @param {AirdropProof?} proof + * @param {AirdropProof?} [proof] */ constructor(proof) { @@ -1784,18 +1774,18 @@ class AirdropPacket extends Packet { /** * Serialize proof packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { this.proof.write(bw); - return this; + return bw; } /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -1815,8 +1805,8 @@ class UnknownPacket extends Packet { /** * Create an unknown packet. * @constructor - * @param {Number|null} type - * @param {Buffer|null} data + * @param {Number?} [type] + * @param {Buffer?} [data] */ constructor(type, data) { @@ -1842,18 +1832,17 @@ class UnknownPacket extends Packet { /** * Serialize unknown packet to writer. - * @param {BufferWriter} bw + * @param {BufioWriter} bw */ write(bw) { bw.writeBytes(this.data); - return this; + return bw; } /** * Inject properties from serialized data. - * @private - * @param {BufferReader} data + * @param {bio.BufferReader} br * @param {Number} type */ diff --git a/lib/net/peer.js b/lib/net/peer.js index c502fab71..f3eb28a41 100644 --- a/lib/net/peer.js +++ b/lib/net/peer.js @@ -35,6 +35,9 @@ const invTypes = InvItem.types; const packetTypes = packets.types; /** @typedef {import('net').Socket} NetSocket */ +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').Rate} Rate */ +/** @typedef {import('../protocol/errors').VerifyError} VerifyError */ /** * Represents a network peer. From e13f180c962ea90fb11166bbefad250a3a59cd6f Mon Sep 17 00:00:00 2001 From: Nodari Chkuaselidze Date: Mon, 30 Sep 2024 14:29:03 +0400 Subject: [PATCH 5/6] types: update blockstore. --- lib/blockstore/abstract.js | 26 ++++++++-------- lib/blockstore/file.js | 63 +++++++++++++++++++++++--------------- lib/blockstore/level.js | 26 +++++++++------- lib/blockstore/records.js | 17 +++++----- lib/primitives/coin.js | 6 ++-- lib/script/sigcache.js | 2 +- 6 files changed, 80 insertions(+), 60 deletions(-) diff --git a/lib/blockstore/abstract.js b/lib/blockstore/abstract.js index d024f3e23..9c2a31b02 100644 --- a/lib/blockstore/abstract.js +++ b/lib/blockstore/abstract.js @@ -20,6 +20,7 @@ class AbstractBlockStore { /** * Create an abstract blockstore. * @constructor + * @param {Object} [options] */ constructor(options) { @@ -192,7 +193,7 @@ class AbstractBlockStore { /** * Create batch. - * @returns {Batch} + * @returns {AbstractBatch} */ batch() { @@ -206,7 +207,6 @@ class AbstractBlockStore { * @abstract */ -// eslint-disable-next-line no-unused-vars class AbstractBatch { /** * Create AbstractBatch. @@ -218,9 +218,9 @@ class AbstractBatch { /** * Write merkle block data to the batch. - * @property {Buffer} hash - * @property {Buffer} data - * @returns {Batch} + * @param {Buffer} hash + * @param {Buffer} data + * @returns {this} */ writeMerkle(hash, data) { @@ -231,7 +231,7 @@ class AbstractBatch { * Write undo coin data to the batch. * @param {Buffer} hash * @param {Buffer} data - * @returns {Batch} + * @returns {this} */ writeUndo(hash, data) { @@ -242,7 +242,7 @@ class AbstractBatch { * Write block data to the batch. * @param {Buffer} hash * @param {Buffer} data - * @returns {Batch} + * @returns {this} */ writeBlock(hash, data) { @@ -252,7 +252,7 @@ class AbstractBatch { /** * Remove merkle block data from the batch. * @param {Buffer} hash - * @returns {Batch} + * @returns {this} */ pruneMerkle(hash) { @@ -262,7 +262,7 @@ class AbstractBatch { /** * Remove undo data from the batch. * @param {Buffer} hash - * @returns {Batch} + * @returns {this} */ pruneUndo(hash) { @@ -272,7 +272,7 @@ class AbstractBatch { /** * Prune block data from the batch. * @param {Buffer} hash - * @returns {Batch} + * @returns {this} */ pruneBlock(hash) { @@ -281,7 +281,7 @@ class AbstractBatch { /** * Clear the batch. - * @returns {Batch} + * @returns {this} */ clear() { @@ -293,11 +293,13 @@ class AbstractBatch { * @returns {Promise} */ - write() { + commit() { throw new Error('Abstract method.'); } } +AbstractBlockStore.AbstractBatch = AbstractBatch; + /* * Expose */ diff --git a/lib/blockstore/file.js b/lib/blockstore/file.js index 188cb3279..b323c0ad7 100644 --- a/lib/blockstore/file.js +++ b/lib/blockstore/file.js @@ -15,6 +15,7 @@ const Network = require('../protocol/network'); const consensus = require('../protocol/consensus'); const Headers = require('../primitives/headers'); const AbstractBlockStore = require('./abstract'); +const {AbstractBatch} = AbstractBlockStore; const {BlockRecord, FileRecord} = require('./records'); const layout = require('./layout'); const {types, prefixes} = require('./common'); @@ -33,6 +34,7 @@ class FileBlockStore extends AbstractBlockStore { /** * Create a blockstore that stores blocks in files. * @constructor + * @param {Object} [options] */ constructor(options) { @@ -234,7 +236,7 @@ class FileBlockStore extends AbstractBlockStore { * @private * @param {Number} type - The type of block data * @param {Number} fileno - The number of the file. - * @returns {Promise} + * @returns {String} */ filepath(type, fileno) { @@ -266,7 +268,7 @@ class FileBlockStore extends AbstractBlockStore { * @private * @param {Number} type - The type of block data * @param {Number} length - The number of bytes - * @returns {Promise} + * @returns {Promise} */ async allocate(type, length) { @@ -321,7 +323,7 @@ class FileBlockStore extends AbstractBlockStore { * This method stores merkle block data in files. * @param {Buffer} hash - The block hash * @param {Buffer} data - The block data - * @returns {Promise} + * @returns {Promise} */ async writeMerkle(hash, data) { @@ -332,7 +334,7 @@ class FileBlockStore extends AbstractBlockStore { * This method stores block undo coin data in files. * @param {Buffer} hash - The block hash * @param {Buffer} data - The block data - * @returns {Promise} + * @returns {Promise} */ async writeUndo(hash, data) { @@ -343,7 +345,7 @@ class FileBlockStore extends AbstractBlockStore { * This method stores block data in files. * @param {Buffer} hash - The block hash * @param {Buffer} data - The block data - * @returns {Promise} + * @returns {Promise} */ async writeBlock(hash, data) { @@ -358,7 +360,7 @@ class FileBlockStore extends AbstractBlockStore { * @param {Number} type - The type of block data * @param {Buffer} hash - The block hash * @param {Buffer} data - The block data - * @returns {Promise} + * @returns {Promise} - Whether the data was written. */ async _write(type, hash, data) { @@ -451,7 +453,7 @@ class FileBlockStore extends AbstractBlockStore { /** * This method will retrieve merkle block data. * @param {Buffer} hash - The block hash - * @returns {Promise} + * @returns {Promise} */ async readMerkle(hash) { @@ -461,7 +463,7 @@ class FileBlockStore extends AbstractBlockStore { /** * This method will retrieve block undo coin data. * @param {Buffer} hash - The block hash - * @returns {Promise} + * @returns {Promise} */ async readUndo(hash) { @@ -488,9 +490,9 @@ class FileBlockStore extends AbstractBlockStore { * @private * @param {Number} type - The type of block data * @param {Buffer} hash - The block hash - * @param {Number} offset - The offset within the block - * @param {Number} length - The number of bytes of the data - * @returns {Promise} + * @param {Number} [offset] - The offset within the block + * @param {Number} [length] - The number of bytes of the data + * @returns {Promise} */ async _read(type, hash, offset, length) { @@ -536,7 +538,7 @@ class FileBlockStore extends AbstractBlockStore { /** * This will free resources for storing merkle block data. * @param {Buffer} hash - The block hash - * @returns {Promise} + * @returns {Promise} */ async pruneMerkle(hash) { @@ -546,7 +548,7 @@ class FileBlockStore extends AbstractBlockStore { /** * This will free resources for storing the block undo coin data. * @param {Buffer} hash - The block hash - * @returns {Promise} + * @returns {Promise} */ async pruneUndo(hash) { @@ -556,7 +558,7 @@ class FileBlockStore extends AbstractBlockStore { /** * This will free resources for storing the block data. * @param {Buffer} hash - The block hash - * @returns {Promise} + * @returns {Promise} */ async pruneBlock(hash) { @@ -569,8 +571,9 @@ class FileBlockStore extends AbstractBlockStore { * block is removed and will not be able to be read. The underlying * file is unlinked when all blocks in a file have been pruned. * @private + * @param {Number} type - The type of block data * @param {Buffer} hash - The block hash - * @returns {Promise} + * @returns {Promise} */ async _prune(type, hash) { @@ -656,13 +659,16 @@ class FileBlockStore extends AbstractBlockStore { * @alias module:blockstore.FileBatch */ -class FileBatch { +class FileBatch extends AbstractBatch { /** * Create AbstractBatch. * @constructor + * @param {FileBlockStore} blocks */ constructor(blocks) { + super(); + this.blocks = blocks; this.writes = []; this.prunes = []; @@ -676,76 +682,83 @@ class FileBatch { /** * Write merkle block data to the batch. - * @property {Buffer} hash - * @property {Buffer} data - * @returns {Batch} + * @param {Buffer} hash + * @param {Buffer} data + * @returns {this} */ writeMerkle(hash, data) { this.writes.push(new WriteOp(types.MERKLE, hash, data)); + return this; } /** * Write undo coin data to the batch. * @param {Buffer} hash * @param {Buffer} data - * @returns {Batch} + * @returns {this} */ writeUndo(hash, data) { this.writes.push(new WriteOp(types.UNDO, hash, data)); + return this; } /** * Write block data to the batch. * @param {Buffer} hash * @param {Buffer} data - * @returns {Batch} + * @returns {this} */ writeBlock(hash, data) { this.writes.push(new WriteOp(types.BLOCK, hash, data)); + return this; } /** * Remove merkle block data from the batch. * @param {Buffer} hash - * @returns {Batch} + * @returns {this} */ pruneMerkle(hash) { this.prunes.push(new PruneOp(types.MERKLE, hash)); + return this; } /** * Remove undo data from the batch. * @param {Buffer} hash - * @returns {Batch} + * @returns {this} */ pruneUndo(hash) { this.prunes.push(new PruneOp(types.UNDO, hash)); + return this; } /** * Prune block data from the batch. * @param {Buffer} hash - * @returns {Batch} + * @returns {this} */ pruneBlock(hash) { this.prunes.push(new PruneOp(types.BLOCK, hash)); + return this; } /** * Clear the batch. - * @returns {Batch} + * @returns {this} */ clear() { assert(!this.written, 'Already written all.'); this.writes.length = 0; this.prunes.length = 0; + return this; } /** diff --git a/lib/blockstore/level.js b/lib/blockstore/level.js index 69eb22e7b..693eeabf9 100644 --- a/lib/blockstore/level.js +++ b/lib/blockstore/level.js @@ -10,6 +10,7 @@ const assert = require('bsert'); const bdb = require('bdb'); const fs = require('bfile'); const AbstractBlockStore = require('./abstract'); +const {AbstractBatch} = require('./abstract'); const layout = require('./layout'); const {types} = require('./common'); @@ -24,6 +25,7 @@ class LevelBlockStore extends AbstractBlockStore { /** * Create a blockstore that stores blocks in LevelDB. * @constructor + * @param {Object} [options] */ constructor(options) { @@ -246,13 +248,15 @@ class LevelBlockStore extends AbstractBlockStore { * @alias module:blockstore.LevelBatch */ -class LevelBatch { +class LevelBatch extends AbstractBatch { /** * Create LevelBatch - * @param {DB} db + * @param {bdb.DB} db */ constructor(db) { + super(); + this.writesBatch = db.batch(); this.prunesBatch = db.batch(); this.committedWrites = false; @@ -265,9 +269,9 @@ class LevelBatch { /** * Write merkle block data to the batch. - * @property {Buffer} hash - * @property {Buffer} data - * @returns {Batch} + * @param {Buffer} hash + * @param {Buffer} data + * @returns {this} */ writeMerkle(hash, data) { @@ -279,7 +283,7 @@ class LevelBatch { * Write undo coin data to the batch. * @param {Buffer} hash * @param {Buffer} data - * @returns {Batch} + * @returns {this} */ writeUndo(hash, data) { @@ -291,7 +295,7 @@ class LevelBatch { * Write block data to the batch. * @param {Buffer} hash * @param {Buffer} data - * @returns {Batch} + * @returns {this} */ writeBlock(hash, data) { @@ -302,7 +306,7 @@ class LevelBatch { /** * Remove merkle block data from the batch. * @param {Buffer} hash - * @returns {Batch} + * @returns {this} */ pruneMerkle(hash) { @@ -313,7 +317,7 @@ class LevelBatch { /** * Remove undo data from the batch. * @param {Buffer} hash - * @returns {Batch} + * @returns {this} */ pruneUndo(hash) { @@ -324,7 +328,7 @@ class LevelBatch { /** * Prune block data from the batch. * @param {Buffer} hash - * @returns {Batch} + * @returns {this} */ pruneBlock(hash) { @@ -334,7 +338,7 @@ class LevelBatch { /** * Clear the batch. - * @returns {Batch} + * @returns {this} */ clear() { diff --git a/lib/blockstore/records.js b/lib/blockstore/records.js index 9c275c938..2236eef7f 100644 --- a/lib/blockstore/records.js +++ b/lib/blockstore/records.js @@ -9,6 +9,8 @@ const assert = require('bsert'); const bio = require('bufio'); +/** @typedef {import('../types').BufioWriter} BufioWriter */ + /** * @module blockstore/records */ @@ -46,8 +48,7 @@ class BlockRecord extends bio.Struct { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} data + * @param {bio.BufferReader} br */ read(br) { @@ -61,8 +62,8 @@ class BlockRecord extends bio.Struct { /** * Serialize the block record. * Write block record to a buffer writer - * @param {BufferWriter} bw - * @returns {BufferWriter} + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -107,8 +108,7 @@ class FileRecord extends bio.Struct { /** * Inject properties from buffer reader. - * @private - * @param {BufferReader} br + * @param {bio.BufferReader} br */ read(br) { @@ -121,14 +121,15 @@ class FileRecord extends bio.Struct { /** * Write serialized file record to the buffer writer. - * @param {BufferWriter} bw - * @returns {BufferWriter} + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { bw.writeU32(this.blocks); bw.writeU32(this.used); bw.writeU32(this.length); + return bw; } } diff --git a/lib/primitives/coin.js b/lib/primitives/coin.js index a1d64a875..cb83b7f36 100644 --- a/lib/primitives/coin.js +++ b/lib/primitives/coin.js @@ -14,8 +14,8 @@ const consensus = require('../protocol/consensus'); const Outpoint = require('./outpoint'); const util = require('../utils/util'); -/** @typedef {import('bufio').BufferWriter} BufferWriter */ /** @typedef {import('bufio').BufferReader} BufferReader */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ /** @typedef {import('../types').NetworkType} NetworkType */ /** @typedef {import('../types').HexHash} HexHash */ /** @typedef {import('./tx')} TX */ @@ -270,8 +270,8 @@ class Coin extends Output { /** * Write the coin to a buffer writer. - * @param {BufferWriter} bw - * @returns {BufferWriter} + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { diff --git a/lib/script/sigcache.js b/lib/script/sigcache.js index 2ba0a86eb..d0e814431 100644 --- a/lib/script/sigcache.js +++ b/lib/script/sigcache.js @@ -95,7 +95,7 @@ class SigCache { /** * Verify a signature, testing * it against the cache first. - * @param {Buffer} hash + * @param {Hash} hash * @param {Buffer} sig * @param {Buffer} key * @returns {Boolean} From 0ce319765a2669cafec32be4f01719efa16831c1 Mon Sep 17 00:00:00 2001 From: Nodari Chkuaselidze Date: Tue, 1 Oct 2024 18:19:26 +0400 Subject: [PATCH 6/6] types: update mempool entries and simple mining. --- lib/blockstore/abstract.js | 3 +- lib/covenants/view.js | 17 ++++ lib/hd/common.js | 2 +- lib/mempool/airdropentry.js | 17 ++-- lib/mempool/claimentry.js | 17 ++-- lib/mempool/contractstate.js | 161 +++++++++++++++++++++++++++++++- lib/mempool/mempoolentry.js | 27 ++++-- lib/mining/common.js | 22 ++--- lib/mining/template.js | 62 +++++++++--- lib/primitives/abstractblock.js | 2 +- lib/primitives/claim.js | 110 ++++++++++++++++++++++ 11 files changed, 386 insertions(+), 54 deletions(-) diff --git a/lib/blockstore/abstract.js b/lib/blockstore/abstract.js index 9c2a31b02..efde2ddf1 100644 --- a/lib/blockstore/abstract.js +++ b/lib/blockstore/abstract.js @@ -298,10 +298,9 @@ class AbstractBatch { } } -AbstractBlockStore.AbstractBatch = AbstractBatch; - /* * Expose */ +AbstractBlockStore.AbstractBatch = AbstractBatch; module.exports = AbstractBlockStore; diff --git a/lib/covenants/view.js b/lib/covenants/view.js index 7302f33e4..462c7a83b 100644 --- a/lib/covenants/view.js +++ b/lib/covenants/view.js @@ -5,11 +5,20 @@ const {BufferMap} = require('buffer-map'); const NameState = require('./namestate'); const NameUndo = require('./undo'); +/** @typedef {import('../types').Hash} Hash */ + class View { constructor() { + /** @type {BufferMap} */ this.names = new BufferMap(); } + /** + * @param {Object} db + * @param {Hash} nameHash + * @returns {NameState} + */ + getNameStateSync(db, nameHash) { assert(db && typeof db.getNameState === 'function'); assert(Buffer.isBuffer(nameHash)); @@ -19,6 +28,7 @@ class View { if (cache) return cache; + /** @type {NameState?} */ const ns = db.getNameState(nameHash); if (!ns) { @@ -33,6 +43,12 @@ class View { return ns; } + /** + * @param {Object} db + * @param {Hash} nameHash + * @returns {Promise} + */ + async getNameState(db, nameHash) { assert(db && typeof db.getNameState === 'function'); assert(Buffer.isBuffer(nameHash)); @@ -42,6 +58,7 @@ class View { if (cache) return cache; + /** @type {NameState?} */ const ns = await db.getNameState(nameHash); if (!ns) { diff --git a/lib/hd/common.js b/lib/hd/common.js index 256dd3259..d5b8482cd 100644 --- a/lib/hd/common.js +++ b/lib/hd/common.js @@ -39,7 +39,7 @@ common.MAX_ENTROPY = 512; /** * LRU cache to avoid deriving keys twice. - * @type {LRU} + * @type {LRU} */ common.cache = new LRU(500); diff --git a/lib/mempool/airdropentry.js b/lib/mempool/airdropentry.js index 2803d37cc..337416e67 100644 --- a/lib/mempool/airdropentry.js +++ b/lib/mempool/airdropentry.js @@ -12,6 +12,11 @@ const policy = require('../protocol/policy'); const util = require('../utils/util'); const Address = require('../primitives/address'); +/** @typedef {import('../types').Amount} AmountValue */ +/** @typedef {import('../types').Rate} Rate */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('../primitives/airdropproof')} AirdropProof */ + /* * Constants */ @@ -73,7 +78,6 @@ class AirdropEntry extends bio.Struct { /** * Inject properties from airdrop. - * @private * @param {AirdropProof} proof * @param {Number} height */ @@ -99,7 +103,6 @@ class AirdropEntry extends bio.Struct { /** * Create a mempool entry from an airdrop proof. * @param {AirdropProof} proof - * @param {Object} data * @param {Number} height - Entry height. * @returns {AirdropEntry} */ @@ -110,7 +113,7 @@ class AirdropEntry extends bio.Struct { /** * Get fee. - * @returns {Amount} + * @returns {AmountValue} */ getFee() { @@ -160,7 +163,8 @@ class AirdropEntry extends bio.Struct { /** * Serialize entry to a buffer. - * @returns {Buffer} + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -180,9 +184,8 @@ class AirdropEntry extends bio.Struct { /** * Inject properties from serialized data. - * @private - * @param {Buffer} data - * @returns {AirdropEntry} + * @param {bio.BufferReader} br + * @returns {this} */ read(br) { diff --git a/lib/mempool/claimentry.js b/lib/mempool/claimentry.js index ac664191d..1da6d4ef9 100644 --- a/lib/mempool/claimentry.js +++ b/lib/mempool/claimentry.js @@ -13,6 +13,11 @@ const util = require('../utils/util'); const Address = require('../primitives/address'); const rules = require('../covenants/rules'); +/** @typedef {import('../primitives/claim')} Claim */ +/** @typedef {import('../types').Amount} AmountValue */ +/** @typedef {import('../types').Rate} Rate */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ + /* * Constants */ @@ -58,7 +63,6 @@ class ClaimEntry extends bio.Struct { /** * Inject properties from options object. - * @private * @param {Object} options */ @@ -84,7 +88,6 @@ class ClaimEntry extends bio.Struct { /** * Inject properties from claim. - * @private * @param {Claim} claim * @param {Object} data * @param {Number} height @@ -128,7 +131,7 @@ class ClaimEntry extends bio.Struct { /** * Get fee. - * @returns {Amount} + * @returns {AmountValue} */ getFee() { @@ -178,7 +181,8 @@ class ClaimEntry extends bio.Struct { /** * Serialize entry to a buffer. - * @returns {Buffer} + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -204,9 +208,8 @@ class ClaimEntry extends bio.Struct { /** * Inject properties from serialized data. - * @private - * @param {Buffer} data - * @returns {ClaimEntry} + * @param {bio.BufferReader} br + * @returns {this} */ read(br) { diff --git a/lib/mempool/contractstate.js b/lib/mempool/contractstate.js index cf0fca700..cbc2948bc 100644 --- a/lib/mempool/contractstate.js +++ b/lib/mempool/contractstate.js @@ -14,6 +14,10 @@ const CoinView = require('../coins/coinview'); const {types} = rules; const {states} = NameState; +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../protocol/network')} Network */ +/** @typedef {import('../primitives/tx')} TX */ + /* * Constants */ @@ -25,6 +29,11 @@ const EMPTY = Buffer.alloc(0); */ class ContractState { + /** + * @constructor + * @param {Network} network + */ + constructor(network) { assert(network); @@ -35,18 +44,23 @@ class ContractState { this.unique = new BufferSet(); // Reference counter. + /** @type {BufferMap} */ this.refs = new BufferMap(); // Map of nameHash->set-of-txids. + /** @type {BufferMap} */ this.opens = new BufferMap(); // Map of nameHash->set-of-txids. + /** @type {BufferMap} */ this.bids = new BufferMap(); // Map of nameHash->set-of-txids. + /** @type {BufferMap} */ this.reveals = new BufferMap(); // Map of nameHash->set-of-txids. + /** @type {BufferMap} */ this.updates = new BufferMap(); // Current on-chain state @@ -65,24 +79,51 @@ class ContractState { return this; } + /** + * @param {Hash} nameHash + * @returns {Boolean} + */ + hasName(nameHash) { return this.unique.has(nameHash); } + /** + * @param {Hash} nameHash + * @returns {ContractState} + */ + addName(nameHash) { this.unique.add(nameHash); return this; } + /** + * @param {Hash} nameHash + * @returns {ContractState} + */ + removeName(nameHash) { this.unique.delete(nameHash); return this; } + /** + * @param {TX} tx + * @returns {Boolean} + */ + hasNames(tx) { return rules.hasNames(tx, this.unique); } + /** + * @param {BufferMap} map + * @param {Hash} nameHash + * @param {Hash} hash + * @returns {ContractState} + */ + addMap(map, nameHash, hash) { let set = map.get(nameHash); @@ -96,6 +137,13 @@ class ContractState { return this; } + /** + * @param {BufferMap} map + * @param {Hash} nameHash + * @param {Hash} hash + * @returns {ContractState} + */ + removeMap(map, nameHash, hash) { const set = map.get(nameHash); @@ -110,38 +158,91 @@ class ContractState { return this; } + /** + * @param {Hash} nameHash + * @param {Hash} hash + * @returns {ContractState} + */ + addOpen(nameHash, hash) { return this.addMap(this.opens, nameHash, hash); } + /** + * @param {Hash} nameHash + * @param {Hash} hash + * @returns {ContractState} + */ + removeOpen(nameHash, hash) { return this.removeMap(this.opens, nameHash, hash); } + /** + * @param {Hash} nameHash + * @param {Hash} hash + * @returns {ContractState} + */ + addBid(nameHash, hash) { return this.addMap(this.bids, nameHash, hash); } + /** + * @param {Hash} nameHash + * @param {Hash} hash + * @returns {ContractState} + */ + removeBid(nameHash, hash) { return this.removeMap(this.bids, nameHash, hash); } + /** + * @param {Hash} nameHash + * @param {Hash} hash + * @returns {ContractState} + */ + addReveal(nameHash, hash) { return this.addMap(this.reveals, nameHash, hash); } + /** + * @param {Hash} nameHash + * @param {Hash} hash + * @returns {ContractState} + */ + removeReveal(nameHash, hash) { return this.removeMap(this.reveals, nameHash, hash); } + /** + * @param {Hash} nameHash + * @param {Hash} hash + * @returns {ContractState} + */ + addUpdate(nameHash, hash) { return this.addMap(this.updates, nameHash, hash); } + /** + * @param {Hash} nameHash + * @param {Hash} hash + * @returns {ContractState} + */ + removeUpdate(nameHash, hash) { return this.removeMap(this.updates, nameHash, hash); } + /** + * @param {Hash} nameHash + * @returns {ContractState} + */ + reference(nameHash) { let count = this.refs.get(nameHash); @@ -155,6 +256,11 @@ class ContractState { return this; } + /** + * @param {Hash} nameHash + * @returns {ContractState} + */ + dereference(nameHash) { let count = this.refs.get(nameHash); @@ -176,6 +282,12 @@ class ContractState { return this; } + /** + * @param {TX} tx + * @param {CoinView} view + * @returns {ContractState} + */ + track(tx, view) { const hash = tx.hash(); @@ -233,6 +345,11 @@ class ContractState { return this; } + /** + * @param {TX} tx + * @returns {ContractState} + */ + untrack(tx) { const hash = tx.hash(); const names = new BufferSet(); @@ -270,6 +387,11 @@ class ContractState { return this; } + /** + * @param {CoinView} view + * @returns {ContractState} + */ + merge(view) { for (const [nameHash, ns] of view.names) { if (!this.refs.has(nameHash)) @@ -284,6 +406,13 @@ class ContractState { return this; } + /** + * @param {BufferMap} map + * @param {Hash} nameHash + * @param {BufferSet} items + * @returns {ContractState} + */ + toSet(map, nameHash, items) { const hashes = map.get(nameHash); @@ -296,24 +425,54 @@ class ContractState { return this; } + /** + * @param {Hash} nameHash + * @param {BufferSet} items + * @returns {ContractState} + */ + handleExpired(nameHash, items) { this.toSet(this.updates, nameHash, items); this.toSet(this.reveals, nameHash, items); return this; } + /** + * @param {Hash} nameHash + * @param {BufferSet} items + * @returns {ContractState} + */ + handleOpen(nameHash, items) { return this.toSet(this.updates, nameHash, items); } + /** + * @param {Hash} nameHash + * @param {BufferSet} items + * @returns {ContractState} + */ + handleBidding(nameHash, items) { return this.toSet(this.opens, nameHash, items); } + /** + * @param {Hash} nameHash + * @param {BufferSet} items + * @returns {ContractState} + */ + handleReveal(nameHash, items) { return this.toSet(this.bids, nameHash, items); } + /** + * @param {Hash} nameHash + * @param {BufferSet} items + * @returns {ContractState} + */ + handleClosed(nameHash, items) { return this.toSet(this.reveals, nameHash, items); } @@ -322,7 +481,7 @@ class ContractState { * Invalidate transactions in the mempool. * @param {Number} height * @param {Boolean} hardened - * @returns {BufferSet} - list of invalidated tx hashes. + * @returns {BufferSet} - list of invalidated tx hashes. */ invalidate(height, hardened) { diff --git a/lib/mempool/mempoolentry.js b/lib/mempool/mempoolentry.js index e6b102e8d..08043fc1c 100644 --- a/lib/mempool/mempoolentry.js +++ b/lib/mempool/mempoolentry.js @@ -11,6 +11,13 @@ const policy = require('../protocol/policy'); const util = require('../utils/util'); const TX = require('../primitives/tx'); +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').HexHash} HexHash */ +/** @typedef {import('../types').Amount} AmountValue */ +/** @typedef {import('../types').Rate} Rate */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('../coins/coinview')} CoinView */ + /** * Mempool Entry * Represents a mempool entry. @@ -26,12 +33,12 @@ class MempoolEntry extends bio.Struct { /** * Create a mempool entry. * @constructor - * @param {Object} options + * @param {Object} [options] * @param {TX} options.tx - Transaction in mempool. * @param {Number} options.height - Entry height. * @param {Number} options.priority - Entry priority. * @param {Number} options.time - Entry time. - * @param {Amount} options.value - Value of on-chain coins. + * @param {AmountValue} options.value - Value of on-chain coins. */ constructor(options) { @@ -57,7 +64,6 @@ class MempoolEntry extends bio.Struct { /** * Inject properties from options object. - * @private * @param {Object} options */ @@ -80,8 +86,8 @@ class MempoolEntry extends bio.Struct { /** * Inject properties from transaction. - * @private * @param {TX} tx + * @param {CoinView} view * @param {Number} height */ @@ -123,6 +129,7 @@ class MempoolEntry extends bio.Struct { /** * Create a mempool entry from a TX. * @param {TX} tx + * @param {CoinView} view * @param {Number} height - Entry height. * @returns {MempoolEntry} */ @@ -171,7 +178,7 @@ class MempoolEntry extends bio.Struct { /** * Get fee. - * @returns {Amount} + * @returns {AmountValue} */ getFee() { @@ -180,7 +187,7 @@ class MempoolEntry extends bio.Struct { /** * Get delta fee. - * @returns {Amount} + * @returns {AmountValue} */ getDeltaFee() { @@ -284,7 +291,8 @@ class MempoolEntry extends bio.Struct { /** * Serialize entry to a buffer. - * @returns {Buffer} + * @param {BufioWriter} bw + * @returns {BufioWriter} */ write(bw) { @@ -303,9 +311,8 @@ class MempoolEntry extends bio.Struct { /** * Inject properties from serialized data. - * @private - * @param {Buffer} data - * @returns {MempoolEntry} + * @param {bio.BufferReader} br + * @returns {this} */ read(br) { diff --git a/lib/mining/common.js b/lib/mining/common.js index dcdc1bd28..27128563d 100644 --- a/lib/mining/common.js +++ b/lib/mining/common.js @@ -34,8 +34,8 @@ const B0 = 0x1; common.swap32 = function swap32(data) { for (let i = 0; i < data.length; i += 4) { - const field = data.readUInt32LE(i, true); - data.writeUInt32BE(field, i, true); + const field = data.readUInt32LE(i); + data.writeUInt32BE(field, i); } return data; @@ -53,20 +53,20 @@ common.double256 = function double256(target) { assert(target.length === 32); - hi = target.readUInt32BE(0, true); - lo = target.readUInt32BE(4, true); + hi = target.readUInt32BE(0); + lo = target.readUInt32BE(4); n += (hi * 0x100000000 + lo) * B192; - hi = target.readUInt32BE(8, true); - lo = target.readUInt32BE(12, true); + hi = target.readUInt32BE(8); + lo = target.readUInt32BE(12); n += (hi * 0x100000000 + lo) * B128; - hi = target.readUInt32BE(16, true); - lo = target.readUInt32BE(20, true); + hi = target.readUInt32BE(16); + lo = target.readUInt32BE(20); n += (hi * 0x100000000 + lo) * B64; - hi = target.readUInt32BE(24, true); - lo = target.readUInt32BE(28, true); + hi = target.readUInt32BE(24); + lo = target.readUInt32BE(28); n += (hi * 0x100000000 + lo) * B0; return n; @@ -113,7 +113,7 @@ common.getTarget = function getTarget(bits) { /** * Get bits from target. * @param {Buffer} data - * @returns {Buffer} + * @returns {Number} */ common.getBits = function getBits(data) { diff --git a/lib/mining/template.js b/lib/mining/template.js index 9540ee486..41dfa7d91 100644 --- a/lib/mining/template.js +++ b/lib/mining/template.js @@ -23,6 +23,14 @@ const CoinView = require('../coins/coinview'); const rules = require('../covenants/rules'); const common = require('./common'); +/** @typedef {import('../types').Amount} AmountValue */ +/** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../primitives/claim')} Claim */ +/** @typedef {import('../primitives/airdropproof')} AirdropProof */ +/** @typedef {import('../mempool/airdropentry')} AirdropEntry */ +/** @typedef {import('../mempool/claimentry')} ClaimEntry */ +/** @typedef {import('../mempool/mempoolentry')} MempoolEntry */ + /* * Constants */ @@ -38,7 +46,7 @@ class BlockTemplate { /** * Create a block template. * @constructor - * @param {Object} options + * @param {Object} [options] */ constructor(options) { @@ -63,7 +71,7 @@ class BlockTemplate { this.witnessRoot = consensus.ZERO_HASH; this.treeRoot = consensus.ZERO_HASH; this.reservedRoot = consensus.ZERO_HASH; - this.coinbase = DUMMY; + this.coinbase = new TX(); this.items = []; this.claims = []; this.airdrops = []; @@ -74,7 +82,6 @@ class BlockTemplate { /** * Inject properties from options. - * @private * @param {Object} options * @returns {BlockTemplate} */ @@ -233,7 +240,7 @@ class BlockTemplate { /** * Calculate the block reward. - * @returns {Amount} + * @returns {AmountValue} */ getReward() { @@ -364,9 +371,10 @@ class BlockTemplate { /** * Create raw block header with given parameters. - * @param {Buffer} extraNonce - * @param {Number} time * @param {Number} nonce + * @param {Number} time + * @param {Buffer} extraNonce + * @param {Buffer} mask * @returns {Buffer} */ @@ -390,10 +398,10 @@ class BlockTemplate { /** * Calculate proof with given parameters. - * @param {Number} nonce1 - * @param {Number} nonce2 + * @param {Number} nonce * @param {Number} time - * @param {Buffer} nonce + * @param {Buffer} extraNonce + * @param {Buffer} mask * @returns {BlockProof} */ @@ -486,6 +494,7 @@ class BlockTemplate { * Add a transaction to the template. * @param {TX} tx * @param {CoinView} view + * @returns {Boolean} */ addTX(tx, view) { @@ -533,7 +542,8 @@ class BlockTemplate { * Add a transaction to the template * (less verification than addTX). * @param {TX} tx - * @param {CoinView?} view + * @param {CoinView?} [view] + * @returns {Boolean} */ pushTX(tx, view) { @@ -566,6 +576,7 @@ class BlockTemplate { * Add a claim to the template. * @param {Claim} claim * @param {Object} data + * @returns {Boolean} */ addClaim(claim, data) { @@ -582,6 +593,7 @@ class BlockTemplate { /** * Add a claim to the template. * @param {AirdropProof} proof + * @returns {Boolean} */ addAirdrop(proof) { @@ -801,9 +813,9 @@ class BlockAirdrop { } /** - * Instantiate block entry from mempool entry. - * @param {ClaimEntry} entry - * @returns {BlockClaim} + * Instantiate block airdrop from mempool airdropentry. + * @param {AirdropEntry} entry + * @returns {BlockAirdrop} */ static fromEntry(entry) { @@ -837,15 +849,27 @@ class BlockProof { this.mask = consensus.ZERO_HASH; } + /** + * @returns {Hash} + */ + hash() { return this.powHash(); } + /** + * @returns {Hash} + */ + shareHash() { const hdr = Headers.fromMiner(this.hdr); return hdr.shareHash(); } + /** + * @returns {Hash} + */ + powHash() { const hash = this.shareHash(); @@ -855,10 +879,20 @@ class BlockProof { return hash; } - verify(target, network) { + /** + * @param {Buffer} target + * @returns {Boolean} + */ + + verify(target) { return this.powHash().compare(target) <= 0; } + /** + * Calculate the target difficulty. + * @returns {Number} + */ + getDifficulty() { return common.getDifficulty(this.powHash()); } diff --git a/lib/primitives/abstractblock.js b/lib/primitives/abstractblock.js index 0d6f8bbcc..fdba21184 100644 --- a/lib/primitives/abstractblock.js +++ b/lib/primitives/abstractblock.js @@ -344,7 +344,7 @@ class AbstractBlock extends bio.Struct { /** * Calculate share hash. - * @returns {Buffer} + * @returns {Hash} */ shareHash() { diff --git a/lib/primitives/claim.js b/lib/primitives/claim.js index 37dab00f5..6b4d4ed4a 100644 --- a/lib/primitives/claim.js +++ b/lib/primitives/claim.js @@ -20,6 +20,10 @@ const Output = require('./output'); const {OwnershipProof} = Ownership; /** @typedef {import('../types').Hash} Hash */ +/** @typedef {import('../types').Amount} AmountValue */ +/** @typedef {import('../types').Rate} Rate */ +/** @typedef {import('../types').BufioWriter} BufioWriter */ +/** @typedef {import('../protocol/network')} Network */ /* * Constants @@ -43,6 +47,10 @@ class Claim extends bio.Struct { this._data = null; } + /** + * @returns {this} + */ + refresh() { this._hash = null; this._data = null; @@ -60,10 +68,19 @@ class Claim extends bio.Struct { return this._hash; } + /** + * @returns {String} + */ + hashHex() { return this.hash().toString('hex'); } + /** + * @param {Network} network + * @returns {Object} + */ + getData(network) { if (!this._data) { const proof = this.getProof(); @@ -82,16 +99,30 @@ class Claim extends bio.Struct { return this._data; } + /** + * @returns {Number} + */ + getSize() { return 2 + this.blob.length; } + /** + * @param {BufioWriter} bw + * @returns {BufioWriter} + */ + write(bw) { bw.writeU16(this.blob.length); bw.writeBytes(this.blob); return bw; } + /** + * @param {Buffer} data + * @returns {this} + */ + decode(data) { const br = bio.read(data); @@ -106,6 +137,11 @@ class Claim extends bio.Struct { return this; } + /** + * @param {bio.BufferReader} br + * @returns {this} + */ + read(br) { const size = br.readU16(); @@ -117,19 +153,37 @@ class Claim extends bio.Struct { return this; } + /** + * @returns {InvItem} + */ + toInv() { return new InvItem(InvItem.types.CLAIM, this.hash()); } + /** + * @returns {Number} + */ + getWeight() { return this.getSize(); } + /** + * @returns {Number} + */ + getVirtualSize() { const scale = consensus.WITNESS_SCALE_FACTOR; return (this.getWeight() + scale - 1) / scale | 0; } + /** + * @param {Number} [size] + * @param {Number} [rate] + * @returns {AmountValue} + */ + getMinFee(size, rate) { if (size == null) size = this.getVirtualSize(); @@ -137,12 +191,23 @@ class Claim extends bio.Struct { return policy.getMinFee(size, rate); } + /** + * @param {Network} [network] + * @returns {AmountValue} + */ + getFee(network) { const data = this.getData(network); assert(data); return data.fee; } + /** + * @param {Number} [size] + * @param {Network} [network] + * @returns {Rate} + */ + getRate(size, network) { const fee = this.getFee(network); @@ -152,6 +217,12 @@ class Claim extends bio.Struct { return policy.getRate(size, fee); } + /** + * @param {Network} network + * @param {Number} height + * @returns {TX} + */ + toTX(network, height) { const data = this.getData(network); assert(data); @@ -193,6 +264,10 @@ class Claim extends bio.Struct { return tx; } + /** + * @returns {OwnershipProof} + */ + getProof() { try { return this.toProof(); @@ -201,35 +276,70 @@ class Claim extends bio.Struct { } } + /** + * @returns {OwnershipProof} + */ + toProof() { return OwnershipProof.decode(this.blob); } + /** + * @returns {Buffer} + */ + toBlob() { return this.blob; } + /** + * @returns {Object} + */ + getJSON() { const proof = this.getProof(); return proof.toJSON(); } + /** + * Inject properties from blob. + * @param {Buffer} blob + * @returns {this} + */ + fromBlob(blob) { assert(Buffer.isBuffer(blob)); this.blob = blob; return this; } + /** + * @param {OwnershipProof} proof + * @returns {this} + */ + fromProof(proof) { assert(proof instanceof OwnershipProof); this.blob = proof.encode(); return this; } + /** + * Instantiate claim from raw proof. + * @param {Buffer} blob + * @returns {Claim} + */ + static fromBlob(blob) { return new this().fromBlob(blob); } + /** + * Instantiate claim from proof. + * @param {OwnershipProof} proof + * @returns {Claim} + */ + static fromProof(proof) { return new this().fromProof(proof); }