diff --git a/etc/sample.conf b/etc/sample.conf index ab89b364..98537436 100644 --- a/etc/sample.conf +++ b/etc/sample.conf @@ -11,6 +11,7 @@ use-workers: true prefix: ~/.bcoin db: leveldb max-files: 64 +cache-size: 100 # fast: false # Logger @@ -22,7 +23,7 @@ log-file: true # witness: true # prune: false use-checkpoints: true -coin-cache: 40000000 +coin-cache: 40 index-tx: false index-address: false diff --git a/lib/blockchain/chain.js b/lib/blockchain/chain.js index 75380728..9a7c35f9 100644 --- a/lib/blockchain/chain.js +++ b/lib/blockchain/chain.js @@ -1410,9 +1410,9 @@ Chain.prototype.finish = function finish(block, entry) { block.txs.length, time); - if (this.db.coinCache.size > 0) { - this.logger.debug('Coin Cache: size=%dmb, total=%d.', - util.mb(this.db.coinCache.size), this.db.coinCache.total); + if (this.db.coinCache.capacity > 0) { + this.logger.debug('Coin Cache: size=%dmb, items=%d.', + util.mb(this.db.coinCache.size), this.db.coinCache.items); } }; diff --git a/lib/blockchain/chaindb.js b/lib/blockchain/chaindb.js index 4ef37175..3887cac0 100644 --- a/lib/blockchain/chaindb.js +++ b/lib/blockchain/chaindb.js @@ -63,10 +63,9 @@ function ChainDB(chain) { this.db = LDB({ location: chain.options.location, db: chain.options.db, - maxOpenFiles: chain.options.maxFiles, + maxFiles: chain.options.maxFiles, + cacheSize: chain.options.cacheSize || (32 << 20), compression: false, - cacheSize: 16 << 20, - writeBufferSize: 8 << 20, bufferKeys: !util.isBrowser }); @@ -800,7 +799,7 @@ ChainDB.prototype.getCoin = co(function* getCoin(hash, index) { if (this.options.spv) return; - if (this.coinCache.size !== 0) { + if (this.coinCache.capacity !== 0) { coins = yield this.getCoins(hash); if (!coins) diff --git a/lib/db/ldb.js b/lib/db/ldb.js index 032e1d61..17b61659 100644 --- a/lib/db/ldb.js +++ b/lib/db/ldb.js @@ -29,20 +29,24 @@ var backends = require('./backends'); function LDB(options) { var target = LDB.getTarget(options); + var cacheSize = options.cacheSize; if (target.backend !== 'rbt') util.mkdir(target.location, true); + if (!cacheSize) + cacheSize = 16 << 20; + return new LowlevelUp(target.location, { // Generic createIfMissing: options.createIfMissing !== false, errorIfExists: options.errorIfExists === true, // LevelDB - compression: options.compression !== false, - cacheSize: options.cacheSize || (8 << 20), - writeBufferSize: options.writeBufferSize || (4 << 20), - maxOpenFiles: options.maxOpenFiles || 64, + compression: options.compression === true, + cacheSize: cacheSize / 2 | 0, + writeBufferSize: cacheSize / 4 | 0, + maxOpenFiles: options.maxFiles || 64, paranoidChecks: false, memory: false, diff --git a/lib/node/config.js b/lib/node/config.js index 7ea737ee..487799ac 100644 --- a/lib/node/config.js +++ b/lib/node/config.js @@ -148,6 +148,7 @@ config.parseData = function parseData(data, prefix, dirname) { options.prefix = path(data.prefix, null, dirname); options.db = str(data.db); options.maxFiles = num(data.maxfiles); + options.cacheSize = mul(data.cachesize, 1024 * 1024); options.fast = bool(data.fast); // Update the prefix if we're using one. @@ -164,7 +165,7 @@ config.parseData = function parseData(data, prefix, dirname) { options.forceWitness = bool(data.forcewitness); options.prune = bool(data.prune); options.useCheckpoints = bool(data.usecheckpoints); - options.coinCache = num(data.coincache); + options.coinCache = mul(data.coincache, 1024 * 1024); options.indexTX = bool(data.indextx); options.indexAddress = bool(data.indexaddress); @@ -643,6 +644,13 @@ function num(value) { return value; } +function mul(value, mult) { + value = num(value); + if (value == null) + return value; + return value * mult; +} + function boolpath(value, prefix, dirname) { if (!value) return null; diff --git a/lib/node/fullnode.js b/lib/node/fullnode.js index 768e8364..1d2eade9 100644 --- a/lib/node/fullnode.js +++ b/lib/node/fullnode.js @@ -74,7 +74,8 @@ function FullNode(options) { coinCache: this.options.coinCache, indexTX: this.options.indexTX, indexAddress: this.options.indexAddress, - maxFiles: this.options.maxFiles + maxFiles: this.options.maxFiles, + cacheSize: this.options.cacheSize }); // Fee estimation. @@ -141,7 +142,8 @@ function FullNode(options) { location: this.location('walletdb'), witness: false, useCheckpoints: this.options.useCheckpoints, - maxFiles: this.options.maxFiles, + maxFiles: this.options.walletMaxFiles, + cacheSize: this.options.walletCacheSize, startHeight: this.options.startHeight, wipeNoReally: this.options.wipeNoReally, resolution: false, diff --git a/lib/node/node.js b/lib/node/node.js index 292b3b59..91dd34fc 100644 --- a/lib/node/node.js +++ b/lib/node/node.js @@ -216,7 +216,8 @@ Node.prototype.parseOptions = function parseOptions(options) { if (options.fast) { options.headers = true; options.useCheckpoints = true; - options.coinCache = 65000000; + options.cacheSize = 300 << 20; + options.coinCache = 100 << 20; } if (options.witness == null) diff --git a/lib/node/spvnode.js b/lib/node/spvnode.js index 22cdf61a..69d03e72 100644 --- a/lib/node/spvnode.js +++ b/lib/node/spvnode.js @@ -54,6 +54,7 @@ function SPVNode(options) { forceWitness: this.options.forceWitness, useCheckpoints: this.options.useCheckpoints, maxFiles: this.options.maxFiles, + cacheSize: this.options.cacheSize, spv: true }); @@ -83,7 +84,8 @@ function SPVNode(options) { db: this.options.db, location: this.location('walletdb'), witness: false, - maxFiles: this.options.maxFiles, + maxFiles: this.options.walletMaxFiles, + cacheSize: this.options.walletCacheSize, startHeight: this.options.startHeight, wipeNoReally: this.options.wipeNoReally, resolution: true, diff --git a/lib/primitives/block.js b/lib/primitives/block.js index 4404aba5..ef8922a6 100644 --- a/lib/primitives/block.js +++ b/lib/primitives/block.js @@ -313,7 +313,7 @@ Block.prototype.createMerkleRoot = function createMerkleRoot(enc) { */ Block.prototype.createWitnessNonce = function createWitnessNonce() { - return crypto.hash256(new Buffer(this.prevBlock, 'hex')); + return util.copy(constants.ZERO_HASH); }; /** diff --git a/lib/utils/lru.js b/lib/utils/lru.js index e553f987..ea8f647d 100644 --- a/lib/utils/lru.js +++ b/lib/utils/lru.js @@ -13,22 +13,23 @@ var assert = require('assert'); * An LRU cache, used for caching {@link ChainEntry}s. * @exports LRU * @constructor - * @param {Number} maxSize + * @param {Number} capacity * @param {Function?} getSize */ -function LRU(maxSize, getSize) { +function LRU(capacity, getSize) { if (!(this instanceof LRU)) - return new LRU(maxSize, getSize); - - this.maxSize = maxSize; - this.getSize = getSize; + return new LRU(capacity, getSize); + assert(typeof capacity === 'number', 'Max size must be a number.'); assert(!getSize || typeof getSize === 'function', 'Bad size callback.'); + this.capacity = capacity; + this.getSize = getSize; + this.map = {}; this.size = 0; - this.total = 0; + this.items = 0; this.head = null; this.tail = null; this.pending = null; @@ -60,14 +61,14 @@ LRU.prototype._getSize = function _getSize(item) { LRU.prototype._compact = function _compact() { var item, next; - if (this.size <= this.maxSize) + if (this.size <= this.capacity) return; for (item = this.head; item; item = next) { - if (this.size <= this.maxSize) + if (this.size <= this.capacity) break; this.size -= this._getSize(item); - this.total--; + this.items--; delete this.map[item.key]; next = item.next; item.prev = null; @@ -93,7 +94,7 @@ LRU.prototype.reset = function reset() { for (item = this.head; item; item = next) { delete this.map[item.key]; - this.total--; + this.items--; next = item.next; item.prev = null; item.next = null; @@ -136,7 +137,7 @@ LRU.prototype.set = function set(key, value) { this._appendList(item); this.size += this._getSize(item); - this.total++; + this.items++; this._compact(); }; @@ -190,7 +191,7 @@ LRU.prototype.remove = function remove(key) { return false; this.size -= this._getSize(item); - this.total--; + this.items--; delete this.map[key]; @@ -469,8 +470,9 @@ function LRUOp(remove, key, value) { */ function NullCache(size) { + this.capacity = 0; this.size = 0; - this.total = 0; + this.items = 0; } NullCache.prototype.set = function set(key, value) {}; diff --git a/lib/wallet/walletdb.js b/lib/wallet/walletdb.js index 7de6909a..012f008b 100644 --- a/lib/wallet/walletdb.js +++ b/lib/wallet/walletdb.js @@ -95,9 +95,9 @@ function WalletDB(options) { this.db = LDB({ location: this.options.location, db: this.options.db, - maxOpenFiles: this.options.maxFiles, - cacheSize: 8 << 20, - writeBufferSize: 4 << 20, + maxFiles: this.options.maxFiles, + cacheSize: this.options.cacheSize, + compression: true, bufferKeys: !util.isBrowser }); } diff --git a/migrate/chaindb0to1.js b/migrate/chaindb0to1.js index af612c47..250aa190 100644 --- a/migrate/chaindb0to1.js +++ b/migrate/chaindb0to1.js @@ -12,8 +12,7 @@ var db = bcoin.ldb({ location: file, db: 'leveldb', compression: true, - cacheSize: 16 << 20, - writeBufferSize: 8 << 20, + cacheSize: 32 << 20, createIfMissing: false, bufferKeys: true }); diff --git a/migrate/chaindb1to2.js b/migrate/chaindb1to2.js index db218763..152b7a8c 100644 --- a/migrate/chaindb1to2.js +++ b/migrate/chaindb1to2.js @@ -23,8 +23,7 @@ db = LDB({ location: file, db: 'leveldb', compression: true, - cacheSize: 16 << 20, - writeBufferSize: 8 << 20, + cacheSize: 32 << 20, createIfMissing: false, bufferKeys: true }); diff --git a/migrate/ensure-tip-index.js b/migrate/ensure-tip-index.js index dfa78f5a..a2af3590 100644 --- a/migrate/ensure-tip-index.js +++ b/migrate/ensure-tip-index.js @@ -19,8 +19,7 @@ db = LDB({ location: file, db: 'leveldb', compression: true, - cacheSize: 16 << 20, - writeBufferSize: 8 << 20, + cacheSize: 32 << 20, createIfMissing: false, bufferKeys: true }); diff --git a/migrate/walletdb2to3.js b/migrate/walletdb2to3.js index 0c890523..295213e4 100644 --- a/migrate/walletdb2to3.js +++ b/migrate/walletdb2to3.js @@ -21,8 +21,7 @@ db = bcoin.ldb({ location: file, db: 'leveldb', compression: true, - cacheSize: 16 << 20, - writeBufferSize: 8 << 20, + cacheSize: 32 << 20, createIfMissing: false, bufferKeys: true }); diff --git a/migrate/walletdb3to4.js b/migrate/walletdb3to4.js index 0a5002c9..b5e90727 100644 --- a/migrate/walletdb3to4.js +++ b/migrate/walletdb3to4.js @@ -22,8 +22,7 @@ db = bcoin.ldb({ location: file, db: 'leveldb', compression: true, - cacheSize: 16 << 20, - writeBufferSize: 8 << 20, + cacheSize: 32 << 20, createIfMissing: false, bufferKeys: true }); diff --git a/migrate/walletdb4to5.js b/migrate/walletdb4to5.js index 0468b9a5..032c3ad1 100644 --- a/migrate/walletdb4to5.js +++ b/migrate/walletdb4to5.js @@ -16,8 +16,7 @@ db = bcoin.ldb({ location: file, db: 'leveldb', compression: true, - cacheSize: 16 << 20, - writeBufferSize: 8 << 20, + cacheSize: 32 << 20, createIfMissing: false, bufferKeys: true }); diff --git a/migrate/walletdb5to6.js b/migrate/walletdb5to6.js index bc5ad879..7883d3d5 100644 --- a/migrate/walletdb5to6.js +++ b/migrate/walletdb5to6.js @@ -16,8 +16,7 @@ db = bcoin.ldb({ location: file, db: 'leveldb', compression: true, - cacheSize: 16 << 20, - writeBufferSize: 8 << 20, + cacheSize: 32 << 20, createIfMissing: false, bufferKeys: true });