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() {
|
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() {
|
FilterLoadPacket.prototype.isWithinConstraints = function isWithinConstraints() {
|
||||||
if (this.filter.size > constants.bloom.MAX_BLOOM_FILTER_SIZE * 8)
|
return this.filter.isWithinConstraints();
|
||||||
return false;
|
|
||||||
|
|
||||||
if (this.filter.n > constants.bloom.MAX_HASH_FUNCS)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -25,7 +25,7 @@ var Block = require('../primitives/block');
|
|||||||
var TX = require('../primitives/tx');
|
var TX = require('../primitives/tx');
|
||||||
var errors = require('../btc/errors');
|
var errors = require('../btc/errors');
|
||||||
var NetAddress = require('../primitives/netaddress');
|
var NetAddress = require('../primitives/netaddress');
|
||||||
var invTypes = constants.inv;
|
var invTypes = InvItem.types;
|
||||||
var packetTypes = packets.types;
|
var packetTypes = packets.types;
|
||||||
var VerifyResult = errors.VerifyResult;
|
var VerifyResult = errors.VerifyResult;
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ function Peer(pool) {
|
|||||||
this.bip151,
|
this.bip151,
|
||||||
this.hostname,
|
this.hostname,
|
||||||
this.outbound,
|
this.outbound,
|
||||||
this.pool.auth,
|
this.pool.authdb,
|
||||||
this.pool.identityKey);
|
this.pool.identityKey);
|
||||||
this.bip151.bip150 = this.bip150;
|
this.bip151.bip150 = this.bip150;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,7 +28,7 @@ var List = require('../utils/list');
|
|||||||
var tcp = require('./tcp');
|
var tcp = require('./tcp');
|
||||||
var dns = require('./dns');
|
var dns = require('./dns');
|
||||||
var HostList = require('./hostlist');
|
var HostList = require('./hostlist');
|
||||||
var invTypes = constants.inv;
|
var invTypes = InvItem.types;
|
||||||
var VerifyError = errors.VerifyError;
|
var VerifyError = errors.VerifyError;
|
||||||
var VerifyResult = errors.VerifyResult;
|
var VerifyResult = errors.VerifyResult;
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ function Pool(options) {
|
|||||||
this.createServer = tcp.createServer;
|
this.createServer = tcp.createServer;
|
||||||
this.resolve = dns.resolve;
|
this.resolve = dns.resolve;
|
||||||
this.locker = new Locker();
|
this.locker = new Locker();
|
||||||
this.auth = null;
|
this.authdb = null;
|
||||||
this.identityKey = null;
|
this.identityKey = null;
|
||||||
this.proxyServer = null;
|
this.proxyServer = null;
|
||||||
this.banTime = constants.BAN_TIME;
|
this.banTime = constants.BAN_TIME;
|
||||||
@ -116,8 +116,8 @@ function Pool(options) {
|
|||||||
this.feeRate = -1;
|
this.feeRate = -1;
|
||||||
|
|
||||||
// Required services.
|
// Required services.
|
||||||
this.needed = constants.services.NETWORK;
|
this.reqServices = constants.services.NETWORK;
|
||||||
this.needed |= constants.services.WITNESS;
|
this.reqServices |= constants.services.WITNESS;
|
||||||
|
|
||||||
this.syncing = false;
|
this.syncing = false;
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ Pool.prototype._initOptions = function _initOptions() {
|
|||||||
|
|
||||||
if (!this.options.witness) {
|
if (!this.options.witness) {
|
||||||
this.address.services &= ~constants.services.WITNESS;
|
this.address.services &= ~constants.services.WITNESS;
|
||||||
this.needed &= ~constants.services.WITNESS;
|
this.reqServices &= ~constants.services.WITNESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.options.host != null) {
|
if (this.options.host != null) {
|
||||||
@ -209,16 +209,26 @@ Pool.prototype._initOptions = function _initOptions() {
|
|||||||
this.proxyServer = this.options.proxyServer;
|
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) {
|
if (this.options.bip150) {
|
||||||
assert(typeof this.options.bip151 === 'boolean');
|
assert(typeof this.options.bip151 === 'boolean');
|
||||||
|
|
||||||
this.auth = new BIP150.AuthDB();
|
this.authdb = new BIP150.AuthDB();
|
||||||
|
|
||||||
if (this.options.authPeers)
|
if (this.options.authPeers)
|
||||||
this.auth.setAuthorized(this.options.authPeers);
|
this.authdb.setAuthorized(this.options.authPeers);
|
||||||
|
|
||||||
if (this.options.knownPeers)
|
if (this.options.knownPeers)
|
||||||
this.auth.setKnown(this.options.knownPeers);
|
this.authdb.setKnown(this.options.knownPeers);
|
||||||
|
|
||||||
this.identityKey = this.options.identityKey || ec.generatePrivateKey();
|
this.identityKey = this.options.identityKey || ec.generatePrivateKey();
|
||||||
|
|
||||||
@ -249,8 +259,8 @@ Pool.prototype._initOptions = function _initOptions() {
|
|||||||
this.hosts.setSeeds([this.options.preferredSeed]);
|
this.hosts.setSeeds([this.options.preferredSeed]);
|
||||||
|
|
||||||
if (this.options.spv) {
|
if (this.options.spv) {
|
||||||
this.spvFilter = Bloom.fromRate(10000, 0.001, constants.bloom.ALL);
|
this.spvFilter = Bloom.fromRate(10000, 0.001, Bloom.flags.ALL);
|
||||||
this.needed |= constants.services.BLOOM;
|
this.reqServices |= constants.services.BLOOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.options.mempool)
|
if (!this.options.mempool)
|
||||||
@ -911,7 +921,7 @@ Pool.prototype.handleAddr = function handleAddr(peer, addrs) {
|
|||||||
if (!addr.isRoutable())
|
if (!addr.isRoutable())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!addr.hasServices(this.needed))
|
if (!addr.hasServices(this.reqServices))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (this.hosts.add(addr, peer.address))
|
if (this.hosts.add(addr, peer.address))
|
||||||
@ -1402,7 +1412,7 @@ Pool.prototype.getHost = function getHost(unique) {
|
|||||||
if (!addr.isValid())
|
if (!addr.isValid())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!addr.hasServices(this.needed))
|
if (!addr.hasServices(this.reqServices))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (now - entry.lastAttempt < 600 && i < 30)
|
if (now - entry.lastAttempt < 600 && i < 30)
|
||||||
|
|||||||
@ -330,7 +330,7 @@ AbstractBlock.prototype.rhash = function() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
AbstractBlock.prototype.toInv = function toInv() {
|
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;
|
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.
|
* Write inv item to buffer writer.
|
||||||
* @param {BufferWriter} bw
|
* @param {BufferWriter} bw
|
||||||
@ -108,11 +140,11 @@ InvItem.fromRaw = function fromRaw(data, enc) {
|
|||||||
|
|
||||||
InvItem.prototype.isBlock = function isBlock() {
|
InvItem.prototype.isBlock = function isBlock() {
|
||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
case constants.inv.BLOCK:
|
case InvItem.types.BLOCK:
|
||||||
case constants.inv.WITNESS_BLOCK:
|
case InvItem.types.WITNESS_BLOCK:
|
||||||
case constants.inv.FILTERED_BLOCK:
|
case InvItem.types.FILTERED_BLOCK:
|
||||||
case constants.inv.WITNESS_FILTERED_BLOCK:
|
case InvItem.types.WITNESS_FILTERED_BLOCK:
|
||||||
case constants.inv.CMPCT_BLOCK:
|
case InvItem.types.CMPCT_BLOCK:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@ -126,8 +158,8 @@ InvItem.prototype.isBlock = function isBlock() {
|
|||||||
|
|
||||||
InvItem.prototype.isTX = function isTX() {
|
InvItem.prototype.isTX = function isTX() {
|
||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
case constants.inv.TX:
|
case InvItem.types.TX:
|
||||||
case constants.inv.WITNESS_TX:
|
case InvItem.types.WITNESS_TX:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@ -140,7 +172,7 @@ InvItem.prototype.isTX = function isTX() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
InvItem.prototype.hasWitness = function hasWitness() {
|
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 Outpoint = require('./outpoint');
|
||||||
var InvItem = require('./invitem');
|
var InvItem = require('./invitem');
|
||||||
var workerPool = require('../workers/workerpool').pool;
|
var workerPool = require('../workers/workerpool').pool;
|
||||||
|
var Bloom = require('../utils/bloom');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constants
|
* Constants
|
||||||
@ -1935,10 +1936,10 @@ TX.prototype.isWatched = function isWatched(filter) {
|
|||||||
output = this.outputs[i];
|
output = this.outputs[i];
|
||||||
// Test the output script
|
// Test the output script
|
||||||
if (output.script.test(filter)) {
|
if (output.script.test(filter)) {
|
||||||
if (filter.update === constants.filterFlags.ALL) {
|
if (filter.update === Bloom.flags.ALL) {
|
||||||
prevout = Outpoint.fromTX(this, i);
|
prevout = Outpoint.fromTX(this, i);
|
||||||
filter.add(prevout.toRaw());
|
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()) {
|
if (output.script.isPubkey() || output.script.isMultisig()) {
|
||||||
prevout = Outpoint.fromTX(this, i);
|
prevout = Outpoint.fromTX(this, i);
|
||||||
filter.add(prevout.toRaw());
|
filter.add(prevout.toRaw());
|
||||||
@ -2016,7 +2017,7 @@ TX.prototype.wtxid = function() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
TX.prototype.toInv = function toInv() {
|
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.BLOOM
|
||||||
| exports.services.WITNESS;
|
| 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.
|
* Script opcodes.
|
||||||
* @enum {Number}
|
* @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} size
|
||||||
* @property {Number} n
|
* @property {Number} n
|
||||||
* @property {Number} tweak
|
* @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) {
|
function Bloom(size, n, tweak, update) {
|
||||||
@ -54,16 +54,70 @@ function Bloom(size, n, tweak, update) {
|
|||||||
tweak = (Math.random() * 0x100000000) >>> 0;
|
tweak = (Math.random() * 0x100000000) >>> 0;
|
||||||
|
|
||||||
if (update == null || update === -1)
|
if (update == null || update === -1)
|
||||||
update = constants.filterFlags.NONE;
|
update = Bloom.flags.NONE;
|
||||||
|
|
||||||
if (typeof update === 'string')
|
if (typeof update === 'string')
|
||||||
update = constants.filterFlags[update.toUpperCase()];
|
update = Bloom.flags[update.toUpperCase()];
|
||||||
|
|
||||||
this.n = n;
|
this.n = n;
|
||||||
this.tweak = tweak;
|
this.tweak = tweak;
|
||||||
this.update = update;
|
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.
|
* Perform the mumur3 hash on data.
|
||||||
* @param {Buffer} val
|
* @param {Buffer} val
|
||||||
@ -164,16 +218,31 @@ Bloom.fromRate = function fromRate(items, rate, update) {
|
|||||||
size = (-1 / LN2SQUARED * items * Math.log(rate)) | 0;
|
size = (-1 / LN2SQUARED * items * Math.log(rate)) | 0;
|
||||||
|
|
||||||
if (update !== -1)
|
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;
|
n = ((size / items * LN2) | 0) || 1;
|
||||||
|
|
||||||
if (update !== -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);
|
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.
|
* Get serialization size.
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
@ -217,7 +286,7 @@ Bloom.prototype.fromReader = function fromReader(br) {
|
|||||||
this.n = br.readU32();
|
this.n = br.readU32();
|
||||||
this.tweak = br.readU32();
|
this.tweak = br.readU32();
|
||||||
this.update = br.readU8();
|
this.update = br.readU8();
|
||||||
assert(constants.filterFlagsByVal[this.update] != null, 'Bad filter flag.');
|
assert(Bloom.flagsByVal[this.update] != null, 'Bad filter flag.');
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -135,7 +135,7 @@ describe('Block', function() {
|
|||||||
it('should create a merkle block', function() {
|
it('should create a merkle block', function() {
|
||||||
var filter, item1, item2, mblock2;
|
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';
|
item1 = '8e7445bbb8abd4b3174d80fa4c409fea6b94d96b';
|
||||||
item2 = '047b00000078da0dca3b0ec2300c00d0ab4466ed10'
|
item2 = '047b00000078da0dca3b0ec2300c00d0ab4466ed10'
|
||||||
|
|||||||
@ -59,7 +59,7 @@ describe('Bloom', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should serialize to the correct format', 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 item1 = '8e7445bbb8abd4b3174d80fa4c409fea6b94d96b';
|
||||||
var item2 = '047b00000078da0dca3b0ec2300c00d0ab4466ed10'
|
var item2 = '047b00000078da0dca3b0ec2300c00d0ab4466ed10'
|
||||||
+ 'e763272c6c9ca052972c69e3884a9022084215e2eef'
|
+ 'e763272c6c9ca052972c69e3884a9022084215e2eef'
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user