From 553312947fe4f3d48d7ff841ea4746343c113268 Mon Sep 17 00:00:00 2001 From: Chris Kleeschulte Date: Thu, 26 Jan 2017 14:57:47 -0500 Subject: [PATCH] Added mempool stuff. --- lib/services/address/index.js | 5 +++-- lib/services/db.js | 2 +- lib/services/transaction.js | 27 +++++++++++++++++++++++---- lib/services/wallet-api/utils.js | 4 ++-- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/lib/services/address/index.js b/lib/services/address/index.js index c764bf25..dc5cefb1 100644 --- a/lib/services/address/index.js +++ b/lib/services/address/index.js @@ -174,7 +174,6 @@ AddressService.prototype.blockHandler = function(block, connectBlock, callback) var address = self._getAddressString(script); if(!address) { - log.warn('Unsupported script type for output in ' + txid); continue; } @@ -214,7 +213,6 @@ AddressService.prototype.blockHandler = function(block, connectBlock, callback) var inputAddress = self._getAddressString(input.script); if(!inputAddress) { - log.warn('Unsupported script for input in transaction ' + txid); continue; } @@ -244,14 +242,17 @@ AddressService.prototype._getAddressString = function(script, output) { return pubkey.toString('hex'); } } catch(e) { + log.warn('Error getting public key from: ', script.toASM(), script.toHex()); // if there is an error, it's because a pubkey can not be extracted from the script // continue on and return null } + //TODO add back in P2PK, but for this we need to look up the utxo for this script if(output && output.script && output.script.isPublicKeyOut()) { return output.script.getPublicKey().toString('hex'); } + log.warn('No utxo given for script spending a P2PK: ', script.toASM(), script.toHex()); return null; }; diff --git a/lib/services/db.js b/lib/services/db.js index ecd4299d..df163167 100644 --- a/lib/services/db.js +++ b/lib/services/db.js @@ -674,7 +674,7 @@ DB.prototype.sync = function() { height = self.tip.__height; return height < self.node.services.bitcoind.height && !self.node.stopping; }, function(done) { - console.log('fetching block ' + (height + 1)); + log.debug('fetching block ' + (height + 1)); self.node.services.bitcoind.getBlock(height + 1, function(err, block) { if (err) { return done(err); diff --git a/lib/services/transaction.js b/lib/services/transaction.js index b2261a18..856eb42a 100644 --- a/lib/services/transaction.js +++ b/lib/services/transaction.js @@ -7,6 +7,8 @@ var bitcore = require('bitcore-lib'); var _ = require('lodash'); var LRU = require('lru-cache'); var utils = require('./wallet-api/utils'); +var index = require('../'); +var log = index.log; /** * The Transaction Service builds upon the Database Service and the Bitcoin Service to add additional * functionality for getting information by bitcoin transaction hash/id. This includes the current @@ -18,6 +20,7 @@ var utils = require('./wallet-api/utils'); function TransactionService(options) { BaseService.call(this, options); this.concurrency = options.concurrency || 20; + this.maxMemPoolSize = options.maxMemPoolSize || 100 * 1024 * 1024; // 100 MB /* upon initialization of the mempool, only txids are obtained from * a trusted bitcoin node (the bitcoind service's rpchost or p2p option) * Since, the mempool is very temporal, I see no reason to take the @@ -27,8 +30,13 @@ function TransactionService(options) { * then call to the trusted bitcoind will take place and the result set. */ this._mempool = LRU({ - max: utils.parseByteCount(options.maxMemPoolSize) || 100 * 1024 * 1024, //100MB - length: function(tx) { if (tx) { return tx.toBuffer().length; } } + max: utils.parseByteCount(this.maxMemPoolSize), + length: function(tx) { + if (tx) { + return tx.toBuffer().length; + } + return 1; + } }); this.currentTransactions = {}; } @@ -84,6 +92,7 @@ TransactionService.prototype.stop = function(callback) { setImmediate(callback); }; +//TODO should we maintain a mempool whilst bitcoind is syncing from a start up to latest height? TransactionService.prototype._updateMempool = function(tx, action) { if (action === 'del') { return this._mempool.del(tx.id); @@ -96,13 +105,22 @@ TransactionService.prototype._updateMempool = function(tx, action) { val = tx; key = tx.id; } - return this._mempool.set(key, val); + this._mempool.set(key, val); + return this._checkMempoolSize(); +}; + +TransactionService.prototype._checkMempoolSize = function() { + var warningPercentage = 80; + var percentage = this._mempool.length / this.maxMemPoolSize * 100.0; + if (percentage >= warningPercentage) { + log.warn('Mempool size has reached ' + percentage + '% of the max size of the mempool (' + this.maxMemPoolSize + 'bytes)'); + } }; TransactionService.prototype.blockHandler = function(block, connectBlock, callback) { var self = this; var action = 'put'; - reverseAction = 'del'; + var reverseAction = 'del'; if (!connectBlock) { action = 'del'; reverseAction = 'put'; @@ -201,6 +219,7 @@ TransactionService.prototype.getTransaction = function(txid, options, callback) }); } + //transaction was not in our mempool, lookup in the database var key = self._encodeTransactionKey(txid); self.node.services.db.store.get(key, function(err, buffer) { diff --git a/lib/services/wallet-api/utils.js b/lib/services/wallet-api/utils.js index 6248fa5d..d8428586 100644 --- a/lib/services/wallet-api/utils.js +++ b/lib/services/wallet-api/utils.js @@ -702,8 +702,8 @@ exports.parseByteCount = function(byteCountString) { return null; } - if (!_.isString) { - return; + if (!_.isString(byteCountString)) { + return byteCountString; } var str = byteCountString.replace(/\s+/g, ''); var map = { 'MB': 1E6, 'kB': 1000, 'KB': 1000, 'MiB': (1024 * 1024),