bloom/net: move bloom constants. net services, move inv types.
This commit is contained in:
parent
3da4542ecb
commit
d1a4e53896
@ -556,7 +556,7 @@ ChainEntry.prototype.toHeaders = function toHeaders() {
|
||||
*/
|
||||
|
||||
ChainEntry.prototype.toInv = function toInv() {
|
||||
return new InvItem(constants.inv.BLOCK, this.hash);
|
||||
return new InvItem(InvItem.types.BLOCK, this.hash);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -2255,13 +2255,7 @@ FilterLoadPacket.fromRaw = function fromRaw(data, enc) {
|
||||
*/
|
||||
|
||||
FilterLoadPacket.prototype.isWithinConstraints = function isWithinConstraints() {
|
||||
if (this.filter.size > constants.bloom.MAX_BLOOM_FILTER_SIZE * 8)
|
||||
return false;
|
||||
|
||||
if (this.filter.n > constants.bloom.MAX_HASH_FUNCS)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return this.filter.isWithinConstraints();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -25,7 +25,7 @@ var Block = require('../primitives/block');
|
||||
var TX = require('../primitives/tx');
|
||||
var errors = require('../btc/errors');
|
||||
var NetAddress = require('../primitives/netaddress');
|
||||
var invTypes = constants.inv;
|
||||
var invTypes = InvItem.types;
|
||||
var packetTypes = packets.types;
|
||||
var VerifyResult = errors.VerifyResult;
|
||||
|
||||
@ -144,7 +144,7 @@ function Peer(pool) {
|
||||
this.bip151,
|
||||
this.hostname,
|
||||
this.outbound,
|
||||
this.pool.auth,
|
||||
this.pool.authdb,
|
||||
this.pool.identityKey);
|
||||
this.bip151.bip150 = this.bip150;
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ var List = require('../utils/list');
|
||||
var tcp = require('./tcp');
|
||||
var dns = require('./dns');
|
||||
var HostList = require('./hostlist');
|
||||
var invTypes = constants.inv;
|
||||
var invTypes = InvItem.types;
|
||||
var VerifyError = errors.VerifyError;
|
||||
var VerifyResult = errors.VerifyResult;
|
||||
|
||||
@ -108,7 +108,7 @@ function Pool(options) {
|
||||
this.createServer = tcp.createServer;
|
||||
this.resolve = dns.resolve;
|
||||
this.locker = new Locker();
|
||||
this.auth = null;
|
||||
this.authdb = null;
|
||||
this.identityKey = null;
|
||||
this.proxyServer = null;
|
||||
this.banTime = constants.BAN_TIME;
|
||||
@ -116,8 +116,8 @@ function Pool(options) {
|
||||
this.feeRate = -1;
|
||||
|
||||
// Required services.
|
||||
this.needed = constants.services.NETWORK;
|
||||
this.needed |= constants.services.WITNESS;
|
||||
this.reqServices = constants.services.NETWORK;
|
||||
this.reqServices |= constants.services.WITNESS;
|
||||
|
||||
this.syncing = false;
|
||||
|
||||
@ -166,7 +166,7 @@ Pool.prototype._initOptions = function _initOptions() {
|
||||
|
||||
if (!this.options.witness) {
|
||||
this.address.services &= ~constants.services.WITNESS;
|
||||
this.needed &= ~constants.services.WITNESS;
|
||||
this.reqServices &= ~constants.services.WITNESS;
|
||||
}
|
||||
|
||||
if (this.options.host != null) {
|
||||
@ -209,16 +209,26 @@ Pool.prototype._initOptions = function _initOptions() {
|
||||
this.proxyServer = this.options.proxyServer;
|
||||
}
|
||||
|
||||
if (this.options.selfish) {
|
||||
assert(typeof this.options.selfish === 'boolean');
|
||||
this.address.services &= ~constants.services.NETWORK;
|
||||
}
|
||||
|
||||
if (this.options.spv) {
|
||||
assert(typeof this.options.spv === 'boolean');
|
||||
this.address.services &= ~constants.services.NETWORK;
|
||||
}
|
||||
|
||||
if (this.options.bip150) {
|
||||
assert(typeof this.options.bip151 === 'boolean');
|
||||
|
||||
this.auth = new BIP150.AuthDB();
|
||||
this.authdb = new BIP150.AuthDB();
|
||||
|
||||
if (this.options.authPeers)
|
||||
this.auth.setAuthorized(this.options.authPeers);
|
||||
this.authdb.setAuthorized(this.options.authPeers);
|
||||
|
||||
if (this.options.knownPeers)
|
||||
this.auth.setKnown(this.options.knownPeers);
|
||||
this.authdb.setKnown(this.options.knownPeers);
|
||||
|
||||
this.identityKey = this.options.identityKey || ec.generatePrivateKey();
|
||||
|
||||
@ -249,8 +259,8 @@ Pool.prototype._initOptions = function _initOptions() {
|
||||
this.hosts.setSeeds([this.options.preferredSeed]);
|
||||
|
||||
if (this.options.spv) {
|
||||
this.spvFilter = Bloom.fromRate(10000, 0.001, constants.bloom.ALL);
|
||||
this.needed |= constants.services.BLOOM;
|
||||
this.spvFilter = Bloom.fromRate(10000, 0.001, Bloom.flags.ALL);
|
||||
this.reqServices |= constants.services.BLOOM;
|
||||
}
|
||||
|
||||
if (!this.options.mempool)
|
||||
@ -911,7 +921,7 @@ Pool.prototype.handleAddr = function handleAddr(peer, addrs) {
|
||||
if (!addr.isRoutable())
|
||||
continue;
|
||||
|
||||
if (!addr.hasServices(this.needed))
|
||||
if (!addr.hasServices(this.reqServices))
|
||||
continue;
|
||||
|
||||
if (this.hosts.add(addr, peer.address))
|
||||
@ -1402,7 +1412,7 @@ Pool.prototype.getHost = function getHost(unique) {
|
||||
if (!addr.isValid())
|
||||
continue;
|
||||
|
||||
if (!addr.hasServices(this.needed))
|
||||
if (!addr.hasServices(this.reqServices))
|
||||
continue;
|
||||
|
||||
if (now - entry.lastAttempt < 600 && i < 30)
|
||||
|
||||
@ -330,7 +330,7 @@ AbstractBlock.prototype.rhash = function() {
|
||||
*/
|
||||
|
||||
AbstractBlock.prototype.toInv = function toInv() {
|
||||
return new InvItem(constants.inv.BLOCK, this.hash('hex'));
|
||||
return new InvItem(InvItem.types.BLOCK, this.hash('hex'));
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@ -28,6 +28,38 @@ function InvItem(type, hash) {
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inv types.
|
||||
* @enum {Number}
|
||||
* @default
|
||||
*/
|
||||
|
||||
InvItem.types = {
|
||||
ERROR: 0,
|
||||
TX: 1,
|
||||
BLOCK: 2,
|
||||
FILTERED_BLOCK: 3,
|
||||
WITNESS_TX: 1 | (1 << 30),
|
||||
WITNESS_BLOCK: 2 | (1 << 30),
|
||||
WITNESS_FILTERED_BLOCK: 3 | (1 << 30),
|
||||
CMPCT_BLOCK: 4
|
||||
};
|
||||
|
||||
/**
|
||||
* Inv types by value.
|
||||
* @const {RevMap}
|
||||
*/
|
||||
|
||||
InvItem.typesByVal = util.revMap(InvItem.types);
|
||||
|
||||
/**
|
||||
* Witness mask for inv types.
|
||||
* @const {Number}
|
||||
* @default
|
||||
*/
|
||||
|
||||
InvItem.WITNESS_MASK = 1 << 30;
|
||||
|
||||
/**
|
||||
* Write inv item to buffer writer.
|
||||
* @param {BufferWriter} bw
|
||||
@ -108,11 +140,11 @@ InvItem.fromRaw = function fromRaw(data, enc) {
|
||||
|
||||
InvItem.prototype.isBlock = function isBlock() {
|
||||
switch (this.type) {
|
||||
case constants.inv.BLOCK:
|
||||
case constants.inv.WITNESS_BLOCK:
|
||||
case constants.inv.FILTERED_BLOCK:
|
||||
case constants.inv.WITNESS_FILTERED_BLOCK:
|
||||
case constants.inv.CMPCT_BLOCK:
|
||||
case InvItem.types.BLOCK:
|
||||
case InvItem.types.WITNESS_BLOCK:
|
||||
case InvItem.types.FILTERED_BLOCK:
|
||||
case InvItem.types.WITNESS_FILTERED_BLOCK:
|
||||
case InvItem.types.CMPCT_BLOCK:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -126,8 +158,8 @@ InvItem.prototype.isBlock = function isBlock() {
|
||||
|
||||
InvItem.prototype.isTX = function isTX() {
|
||||
switch (this.type) {
|
||||
case constants.inv.TX:
|
||||
case constants.inv.WITNESS_TX:
|
||||
case InvItem.types.TX:
|
||||
case InvItem.types.WITNESS_TX:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -140,7 +172,7 @@ InvItem.prototype.isTX = function isTX() {
|
||||
*/
|
||||
|
||||
InvItem.prototype.hasWitness = function hasWitness() {
|
||||
return (this.type & constants.WITNESS_MASK) !== 0;
|
||||
return (this.type & InvItem.WITNESS_MASK) !== 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -25,6 +25,7 @@ var Output = require('./output');
|
||||
var Outpoint = require('./outpoint');
|
||||
var InvItem = require('./invitem');
|
||||
var workerPool = require('../workers/workerpool').pool;
|
||||
var Bloom = require('../utils/bloom');
|
||||
|
||||
/*
|
||||
* Constants
|
||||
@ -1935,10 +1936,10 @@ TX.prototype.isWatched = function isWatched(filter) {
|
||||
output = this.outputs[i];
|
||||
// Test the output script
|
||||
if (output.script.test(filter)) {
|
||||
if (filter.update === constants.filterFlags.ALL) {
|
||||
if (filter.update === Bloom.flags.ALL) {
|
||||
prevout = Outpoint.fromTX(this, i);
|
||||
filter.add(prevout.toRaw());
|
||||
} else if (filter.update === constants.filterFlags.PUBKEY_ONLY) {
|
||||
} else if (filter.update === Bloom.flags.PUBKEY_ONLY) {
|
||||
if (output.script.isPubkey() || output.script.isMultisig()) {
|
||||
prevout = Outpoint.fromTX(this, i);
|
||||
filter.add(prevout.toRaw());
|
||||
@ -2016,7 +2017,7 @@ TX.prototype.wtxid = function() {
|
||||
*/
|
||||
|
||||
TX.prototype.toInv = function toInv() {
|
||||
return new InvItem(constants.inv.TX, this.hash('hex'));
|
||||
return new InvItem(InvItem.types.TX, this.hash('hex'));
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -81,83 +81,6 @@ exports.LOCAL_SERVICES = 0
|
||||
| exports.services.BLOOM
|
||||
| exports.services.WITNESS;
|
||||
|
||||
/**
|
||||
* Inv types.
|
||||
* @enum {Number}
|
||||
* @default
|
||||
*/
|
||||
|
||||
exports.inv = {
|
||||
ERROR: 0,
|
||||
TX: 1,
|
||||
BLOCK: 2,
|
||||
FILTERED_BLOCK: 3,
|
||||
WITNESS_TX: 1 | (1 << 30),
|
||||
WITNESS_BLOCK: 2 | (1 << 30),
|
||||
WITNESS_FILTERED_BLOCK: 3 | (1 << 30),
|
||||
CMPCT_BLOCK: 4
|
||||
};
|
||||
|
||||
/**
|
||||
* Inv types by value.
|
||||
* @const {RevMap}
|
||||
*/
|
||||
|
||||
exports.invByVal = util.revMap(exports.inv);
|
||||
|
||||
/**
|
||||
* Witness mask for inv types.
|
||||
* @const {Number}
|
||||
* @default
|
||||
*/
|
||||
|
||||
exports.WITNESS_MASK = 1 << 30;
|
||||
|
||||
/**
|
||||
* Bloom filter update flags.
|
||||
* @enum {Number}
|
||||
* @default
|
||||
*/
|
||||
|
||||
exports.filterFlags = {
|
||||
/**
|
||||
* Never update the filter with outpoints.
|
||||
*/
|
||||
|
||||
NONE: 0,
|
||||
|
||||
/**
|
||||
* Always update the filter with outpoints.
|
||||
*/
|
||||
|
||||
ALL: 1,
|
||||
|
||||
/**
|
||||
* Only update the filter with outpoints if it is
|
||||
* "asymmetric" in terms of addresses (pubkey/multisig).
|
||||
*/
|
||||
|
||||
PUBKEY_ONLY: 2
|
||||
};
|
||||
|
||||
/**
|
||||
* Bloom filter limits.
|
||||
* @enum {Number}
|
||||
* @default
|
||||
*/
|
||||
|
||||
exports.bloom = {
|
||||
MAX_BLOOM_FILTER_SIZE: 36000,
|
||||
MAX_HASH_FUNCS: 50
|
||||
};
|
||||
|
||||
/**
|
||||
* Bloom filter update flags by value.
|
||||
* @const {RevMap}
|
||||
*/
|
||||
|
||||
exports.filterFlagsByVal = util.revMap(exports.filterFlags);
|
||||
|
||||
/**
|
||||
* Script opcodes.
|
||||
* @enum {Number}
|
||||
|
||||
509
lib/types.js
509
lib/types.js
@ -1,509 +0,0 @@
|
||||
/**
|
||||
* An inverse enum. Retrieves key by value.
|
||||
* @typedef {Object} RevMap
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Path
|
||||
* @property {String} name - Account name.
|
||||
* @property {Number} account - Account index.
|
||||
* @property {Number} change - Change chain.
|
||||
* @property {Number} index - Address index.
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* One of {@link module:constants.inv}.
|
||||
* @typedef {Number|String} InvType
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Outpoint
|
||||
* @property {Hash} hash
|
||||
* @property {Number} index
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* An output script type.
|
||||
* @see {module:constants.scriptTypes}
|
||||
* May sometimes be a string if specified.
|
||||
* @typedef {Number|String} ScriptType
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* A subset of {@link ScriptType}, including
|
||||
* pubkeyhash, scripthash, witnesspubkeyhash,
|
||||
* and witnessscripthash. This value
|
||||
* specifically refers to the address prefix.
|
||||
* It is a network-agnostic way of representing
|
||||
* prefixes. May sometimes be a string if
|
||||
* specified.
|
||||
* @typedef {Number|String} AddressType
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* A bitfield containing locktime flags.
|
||||
* @typedef {Number} LockFlags
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* A map of address hashes ({@link Hash} -> value).
|
||||
* @typedef {Object} AddressMap
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ParsedURI
|
||||
* @property {Base58Address} address
|
||||
* @property {Amount?} amount? - Amount in satoshis.
|
||||
* @property {String?} label
|
||||
* @property {String?} message
|
||||
* @property {String?} request - Payment request URL.
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wallet ID
|
||||
* @typedef {String} WalletID
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base58 string.
|
||||
* @typedef {String} Base58String
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base58 address.
|
||||
* @typedef {String} Base58Address
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* Buffer or hex-string hash.
|
||||
* @typedef {Buffer|String} Hash
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reversed hex-string hash (uint256le).
|
||||
* @typedef {String} ReversedHash
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* Signature hash type. One of `all`, `single`, `none`, or
|
||||
* one of {@link constants.hashType}.
|
||||
* @typedef {String|Number} SighashType
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wallet balance.
|
||||
* @typedef {Object} Balance
|
||||
* @property {Amount} confirmed
|
||||
* @property {Amount} unconfirmed
|
||||
* @property {Amount} total
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* A satoshi amount. This is technically a
|
||||
* JS double float, but it is regularly
|
||||
* enforced to be less than 53 bits and
|
||||
* less than MAX_MONEY in various
|
||||
* functions.
|
||||
* @typedef {Number} Amount
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* Rate of satoshis per kB.
|
||||
* @typedef {Amount} Rate
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* A big number (bn.js)
|
||||
* @typedef {Object} BN
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* A bitfield containing script verify flags.
|
||||
* @typedef {Number} VerifyFlags
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Orphan
|
||||
* @property {Hash} hash - Orphan TX hash.
|
||||
* @property {Number} index - Orphan input index.
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} CoinSelection
|
||||
* @property {Coin[]?} chosen - Selected coins.
|
||||
* @property {Amount} change - Amount of change to add.
|
||||
* @property {Amount} fee - Estimated fee.
|
||||
* @property {Amount} total - Total value.
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} DeploymentState
|
||||
* @property {VerifyFlags} flags
|
||||
* @property {LockFlags} lockFlags
|
||||
* @property {Boolean} coinbaseHeight - Whether coinbase height is enforced.
|
||||
* @property {Boolean} segwit
|
||||
* @property {Boolean} csv
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} SubmitOrderPacket
|
||||
* @property {Hash} hash
|
||||
* @property {TX} tx
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ReplyPacket
|
||||
* @property {Hash} hash
|
||||
* @property {Number} code
|
||||
* @property {Buffer} publicKey
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} FilterLoadPacket
|
||||
* @see Bloom
|
||||
* @property {Buffer} filter - Serialized bloom filter.
|
||||
* @property {Number} n - Number of hash functions.
|
||||
* @property {Number} tweak - Bloom filter seed.
|
||||
* @property {String|Number} update (See {@link constants.filterFlags}).
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} FilterAddPacket
|
||||
* @see Bloom
|
||||
* @property {Buffer} data - Data to add to filter.
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} GetUTXOsPacket
|
||||
* @property {Boolean} mempool - Check mempool.
|
||||
* @property {Outpoint[]} prevout - Outpoints.
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} NakedCoin
|
||||
* @property {Number} version - Transaction version.
|
||||
* @property {Number} height - Transaction height (-1 if unconfirmed).
|
||||
* @property {Amount} value - Output value in satoshis.
|
||||
* @property {Script} script - Output script.
|
||||
* @property {Boolean} coinbase - Whether the containing
|
||||
* transaction is a coinbase.
|
||||
* @property {Hash} hash - Transaction hash.
|
||||
* @property {Number} index - Output index.
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} UTXOsPacket
|
||||
* @property {Array?} data.hits - Hits (array of
|
||||
* 1s and 0s representing a bit mask).
|
||||
* @property {Buffer?} data.map - Hit map.
|
||||
* @property {Object} data.height - Chain height.
|
||||
* @property {Hash} data.tip - Chain tip hash.
|
||||
* @property {Coin[]} data.coins
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} PingPacket
|
||||
* @property {BN} nonce
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} NakedBlock
|
||||
* @property {Number} version - Transaction version. Note that BCoin reads
|
||||
* versions as unsigned even though they are signed at the protocol level.
|
||||
* This value will never be negative.
|
||||
* @property {Hash} prevBlock
|
||||
* @property {Hash} merkleRoot
|
||||
* @property {Number} ts
|
||||
* @property {Number} bits
|
||||
* @property {Number} nonce
|
||||
* @property {Number} height
|
||||
* @property {Number} totalTX
|
||||
* @property {NakedTX[]?} txs - Only present on blocks.
|
||||
* @property {Hash[]?} hashes - Only present on merkleblocks.
|
||||
* @property {Buffer?} flags - Only present on merkleblocks.
|
||||
* @property {Number?} coinbaseHeight - Only present on compactblocks.
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} NakedInput
|
||||
* @property {Outpoint} prevout
|
||||
* @property {NakedScript} script - Input script.
|
||||
* @property {Number} sequence - nSequence.
|
||||
* @property {NakedWitness} witness - Witness.
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} NakedOutput
|
||||
* @property {Amount} value - Value in satoshis.
|
||||
* @property {NakedScript} script - Output script.
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} NakedCoin
|
||||
* @property {Number} version - Transaction version.
|
||||
* @property {Number} height - Transaction height (-1 if unconfirmed).
|
||||
* @property {Amount} value - Output value in satoshis.
|
||||
* @property {Script} script - Output script.
|
||||
* @property {Boolean} coinbase - Whether the containing
|
||||
* transaction is a coinbase.
|
||||
* @property {Hash} hash - Transaction hash.
|
||||
* @property {Number} index - Output index.
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} NakedTX
|
||||
* @property {Number} version
|
||||
* @property {Number} flag
|
||||
* @property {NakedInput[]} inputs
|
||||
* @property {NakedOutput[]} outputs
|
||||
* @property {Number} locktime
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} NakedScript
|
||||
* @property {Buffer} raw - Raw code.
|
||||
* @property {Array} code - Parsed code.
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} NakedWitness
|
||||
* @property {Buffer[]} items - Stack items.
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} FeeFilterPacket
|
||||
* @property {Rate} rate
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* One of `main`, `testnet`, `regtest`, `segnet3`, `segnet4`.
|
||||
* @typedef {String} NetworkType
|
||||
* @see {module:network.types}
|
||||
* @global
|
||||
*/
|
||||
|
||||
/*
|
||||
* Callbacks & Events
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback TXCallback
|
||||
* @param {Error?} err
|
||||
* @param {TX} tx
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback TXSCallback
|
||||
* @param {Error?} err
|
||||
* @param {TX[]} txs
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback MTXCallback
|
||||
* @param {Error?} err
|
||||
* @param {MTX} tx
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback MTXSCallback
|
||||
* @param {Error?} err
|
||||
* @param {MTX[]} txs
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback CoinCallback
|
||||
* @param {Error?} err
|
||||
* @param {Coin} tx
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback CoinsCallback
|
||||
* @param {Error?} err
|
||||
* @param {Coin[]} tx
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback VerifyCallback
|
||||
* @param {VerifyError?} err
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback BlockCallback
|
||||
* @param {Error?} err
|
||||
* @param {Block} block
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback EntryCallback
|
||||
* @param {Error?} err
|
||||
* @param {ChainEntry} entry
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback EntriesCallback
|
||||
* @param {Error?} err
|
||||
* @param {ChainEntry[]} entry
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback BalanceCallback
|
||||
* @param {Error?} err
|
||||
* @param {Balance} balance
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback BooleanCallback
|
||||
* @param {Error?} err
|
||||
* @param {Boolean} result
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback NumberCallback
|
||||
* @param {Error?} err
|
||||
* @param {Number} result
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback HashCallback
|
||||
* @param {Error?} err
|
||||
* @param {Hash} hash
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback HashesCallback
|
||||
* @param {Error?} err
|
||||
* @param {Hash[]} hash
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback WalletCallback
|
||||
* @param {Error?} err
|
||||
* @param {Wallet|NakedWallet} wallet
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback BufferCallback
|
||||
* @param {Error?} err
|
||||
* @param {Buffer} data
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback ObjectCallback
|
||||
* @param {Error?} err
|
||||
* @param {Object} obj
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback DeploymentCallback
|
||||
* @param {(Error|VerifyError)?} err
|
||||
* @param {DeploymentState} state
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback MinerBlockCallback
|
||||
* @param {Error?} err
|
||||
* @param {MinerBlock} block
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback AddressMapCallback
|
||||
* @param {Error?} err
|
||||
* @param {AddressMap} map
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback AddressTableCallback
|
||||
* @param {Error?} err
|
||||
* @param {AddressTable} table
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback OrphanCallback
|
||||
* @param {Error?} err
|
||||
* @param {Orphan} orphan
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback TSHeightCallback
|
||||
* @param {Error?} err
|
||||
* @param {Number} ts
|
||||
* @param {Number} height
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback ConfidenceCallback
|
||||
* @param {Error?} err
|
||||
* @param {Confidence} confidence
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback HashHeightCallback
|
||||
* @param {Error?} err
|
||||
* @param {Hash} hash
|
||||
* @param {Number} height
|
||||
* @global
|
||||
*/
|
||||
@ -34,7 +34,7 @@ var LN2 = 0.6931471805599453094172321214581765680755001343602552;
|
||||
* @property {Number} size
|
||||
* @property {Number} n
|
||||
* @property {Number} tweak
|
||||
* @property {Number} update - Update flag (see {@link constants.filterFlags}).
|
||||
* @property {Number} update - Update flag (see {@link Bloom.flags}).
|
||||
*/
|
||||
|
||||
function Bloom(size, n, tweak, update) {
|
||||
@ -54,16 +54,70 @@ function Bloom(size, n, tweak, update) {
|
||||
tweak = (Math.random() * 0x100000000) >>> 0;
|
||||
|
||||
if (update == null || update === -1)
|
||||
update = constants.filterFlags.NONE;
|
||||
update = Bloom.flags.NONE;
|
||||
|
||||
if (typeof update === 'string')
|
||||
update = constants.filterFlags[update.toUpperCase()];
|
||||
update = Bloom.flags[update.toUpperCase()];
|
||||
|
||||
this.n = n;
|
||||
this.tweak = tweak;
|
||||
this.update = update;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bloom filter update flags.
|
||||
* @enum {Number}
|
||||
* @default
|
||||
*/
|
||||
|
||||
Bloom.flags = {
|
||||
/**
|
||||
* Never update the filter with outpoints.
|
||||
*/
|
||||
|
||||
NONE: 0,
|
||||
|
||||
/**
|
||||
* Always update the filter with outpoints.
|
||||
*/
|
||||
|
||||
ALL: 1,
|
||||
|
||||
/**
|
||||
* Only update the filter with outpoints if it is
|
||||
* "asymmetric" in terms of addresses (pubkey/multisig).
|
||||
*/
|
||||
|
||||
PUBKEY_ONLY: 2
|
||||
};
|
||||
|
||||
/**
|
||||
* Bloom filter update flags by value.
|
||||
* @const {RevMap}
|
||||
*/
|
||||
|
||||
Bloom.flagsByVal = {
|
||||
0: 'NONE',
|
||||
1: 'ALL',
|
||||
2: 'PUBKEY_ONLY'
|
||||
};
|
||||
|
||||
/**
|
||||
* Max bloom filter size.
|
||||
* @const {Number}
|
||||
* @default
|
||||
*/
|
||||
|
||||
Bloom.MAX_BLOOM_FILTER_SIZE = 36000;
|
||||
|
||||
/**
|
||||
* Max number of hash functions.
|
||||
* @const {Number}
|
||||
* @default
|
||||
*/
|
||||
|
||||
Bloom.MAX_HASH_FUNCS = 50;
|
||||
|
||||
/**
|
||||
* Perform the mumur3 hash on data.
|
||||
* @param {Buffer} val
|
||||
@ -164,16 +218,31 @@ Bloom.fromRate = function fromRate(items, rate, update) {
|
||||
size = (-1 / LN2SQUARED * items * Math.log(rate)) | 0;
|
||||
|
||||
if (update !== -1)
|
||||
size = Math.min(size, constants.bloom.MAX_BLOOM_FILTER_SIZE * 8);
|
||||
size = Math.min(size, Bloom.MAX_BLOOM_FILTER_SIZE * 8);
|
||||
|
||||
n = ((size / items * LN2) | 0) || 1;
|
||||
|
||||
if (update !== -1)
|
||||
n = Math.min(n, constants.bloom.MAX_HASH_FUNCS);
|
||||
n = Math.min(n, Bloom.MAX_HASH_FUNCS);
|
||||
|
||||
return new Bloom(size, n, -1, update);
|
||||
};
|
||||
|
||||
/**
|
||||
* Ensure the filter is within the size limits.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Bloom.prototype.isWithinConstraints = function isWithinConstraints() {
|
||||
if (this.size > Bloom.MAX_BLOOM_FILTER_SIZE * 8)
|
||||
return false;
|
||||
|
||||
if (this.n > Bloom.MAX_HASH_FUNCS)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get serialization size.
|
||||
* @returns {Number}
|
||||
@ -217,7 +286,7 @@ Bloom.prototype.fromReader = function fromReader(br) {
|
||||
this.n = br.readU32();
|
||||
this.tweak = br.readU32();
|
||||
this.update = br.readU8();
|
||||
assert(constants.filterFlagsByVal[this.update] != null, 'Bad filter flag.');
|
||||
assert(Bloom.flagsByVal[this.update] != null, 'Bad filter flag.');
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
@ -135,7 +135,7 @@ describe('Block', function() {
|
||||
it('should create a merkle block', function() {
|
||||
var filter, item1, item2, mblock2;
|
||||
|
||||
filter = Bloom.fromRate(1000, 0.01, constants.filterFlags.NONE);
|
||||
filter = Bloom.fromRate(1000, 0.01, Bloom.flags.NONE);
|
||||
|
||||
item1 = '8e7445bbb8abd4b3174d80fa4c409fea6b94d96b';
|
||||
item2 = '047b00000078da0dca3b0ec2300c00d0ab4466ed10'
|
||||
|
||||
@ -59,7 +59,7 @@ describe('Bloom', function() {
|
||||
});
|
||||
|
||||
it('should serialize to the correct format', function() {
|
||||
var filter = new Bloom(952, 6, 3624314491, constants.filterFlags.NONE);
|
||||
var filter = new Bloom(952, 6, 3624314491, Bloom.flags.NONE);
|
||||
var item1 = '8e7445bbb8abd4b3174d80fa4c409fea6b94d96b';
|
||||
var item2 = '047b00000078da0dca3b0ec2300c00d0ab4466ed10'
|
||||
+ 'e763272c6c9ca052972c69e3884a9022084215e2eef'
|
||||
|
||||
Loading…
Reference in New Issue
Block a user