commit
a7cd4e6171
|
@ -42,15 +42,10 @@ Insight.prototype._doRequest = function(args, cb) {
|
|||
}
|
||||
};
|
||||
|
||||
if (log.level == 'verbose') {
|
||||
var s = JSON.stringify(args);
|
||||
|
||||
if ( s.length > 100 )
|
||||
s= s.substr(0,100) + '...';
|
||||
|
||||
log.debug('', 'Insight Q: %s', s);
|
||||
}
|
||||
|
||||
requestList(_.defaults(args, opts), cb);
|
||||
};
|
||||
|
||||
|
@ -71,8 +66,6 @@ Insight.prototype.getUtxos = function(addresses, cb) {
|
|||
},
|
||||
};
|
||||
|
||||
log.info('','Querying utxos: %s addrs', addresses.length);
|
||||
|
||||
this._doRequest(args, function(err, res, unspent) {
|
||||
if (err || res.statusCode !== 200) return cb(_parseErr(err, res));
|
||||
return cb(null, unspent);
|
||||
|
@ -134,8 +127,6 @@ Insight.prototype.getTransactions = function(addresses, from, to, cb) {
|
|||
};
|
||||
|
||||
|
||||
log.info('','Querying addresses: %s addrs', addresses.length);
|
||||
|
||||
this._doRequest(args, function(err, res, txs) {
|
||||
if (err || res.statusCode !== 200) return cb(_parseErr(err, res));
|
||||
|
||||
|
|
|
@ -137,7 +137,6 @@ ExpressApp.prototype.start = function(opts, cb) {
|
|||
};
|
||||
|
||||
function getServer(req, res) {
|
||||
log.heading = '<>';
|
||||
var opts = {
|
||||
clientVersion: req.header('x-client-version'),
|
||||
};
|
||||
|
@ -179,9 +178,6 @@ ExpressApp.prototype.start = function(opts, cb) {
|
|||
// For logging
|
||||
req.walletId = server.walletId;
|
||||
req.copayerId = server.copayerId;
|
||||
|
||||
log.heading = '<' + req.walletId + '>';
|
||||
|
||||
return cb(server);
|
||||
});
|
||||
};
|
||||
|
|
154
lib/server.js
154
lib/server.js
|
@ -8,6 +8,7 @@ var config = require('../config');
|
|||
|
||||
log.debug = log.verbose;
|
||||
log.disableColor();
|
||||
|
||||
var EmailValidator = require('email-validator');
|
||||
var Stringify = require('json-stable-stringify');
|
||||
|
||||
|
@ -272,6 +273,28 @@ WalletService.prototype._runLocked = function(cb, task) {
|
|||
this.lock.runLocked(this.walletId, cb, task);
|
||||
};
|
||||
|
||||
|
||||
WalletService.prototype.logi = function() {
|
||||
if (!this) return log.info.apply(this, arguments);
|
||||
if (!this.walletId) return log.info.apply(this, arguments);
|
||||
|
||||
var args = [].slice.call(arguments);
|
||||
args.unshift('<' + this.walletId + '>');
|
||||
log.info.apply(this, args);
|
||||
};
|
||||
|
||||
|
||||
WalletService.prototype.logw = function() {
|
||||
if (!this) return log.info.apply(this, arguments);
|
||||
if (!this.walletId) return log.info.apply(this, arguments);
|
||||
|
||||
var args = [].slice.call(arguments);
|
||||
args.unshift('<' + this.walletId + '>');
|
||||
log.warn.apply(this, args);
|
||||
};
|
||||
|
||||
|
||||
|
||||
WalletService.prototype.login = function(opts, cb) {
|
||||
var self = this;
|
||||
|
||||
|
@ -381,7 +404,7 @@ WalletService.prototype.createWallet = function(opts, cb) {
|
|||
addressType: addressType,
|
||||
});
|
||||
self.storage.storeWallet(wallet, function(err) {
|
||||
log.debug('Wallet created', wallet.id, opts.network);
|
||||
self.logi('Wallet created', wallet.id, opts.network);
|
||||
newWallet = wallet;
|
||||
return acb(err);
|
||||
});
|
||||
|
@ -597,7 +620,7 @@ WalletService.prototype._notify = function(type, data, opts, cb) {
|
|||
}
|
||||
opts = opts || {};
|
||||
|
||||
log.debug('Notification', type, data);
|
||||
//self.logi('Notification', type);
|
||||
|
||||
cb = cb || function() {};
|
||||
|
||||
|
@ -1068,7 +1091,7 @@ WalletService.prototype._getBlockchainExplorer = function(coin, network) {
|
|||
try {
|
||||
bc = new BlockchainExplorer(opts);
|
||||
} catch (ex) {
|
||||
log.warn('Could not instantiate blockchain explorer', ex);
|
||||
this.logw('Could not instantiate blockchain explorer', ex);
|
||||
}
|
||||
return bc;
|
||||
};
|
||||
|
@ -1082,6 +1105,9 @@ WalletService.prototype._getUtxos = function(coin, addresses, cb) {
|
|||
|
||||
var bc = self._getBlockchainExplorer(coin, networkName);
|
||||
if (!bc) return cb(new Error('Could not get blockchain explorer instance'));
|
||||
|
||||
self.logi('','Querying utxos: %s addrs', addresses.length);
|
||||
|
||||
bc.getUtxos(addresses, function(err, utxos) {
|
||||
if (err) return cb(err);
|
||||
|
||||
|
@ -1260,7 +1286,7 @@ WalletService.prototype._getBalanceFromAddresses = function(opts, cb, i) {
|
|||
|
||||
self.storage.storeBalanceCache(self.walletId, opts.addresses, balance, function(err) {
|
||||
if (err)
|
||||
log.warn('Could not save cache:',err);
|
||||
self.logw('Could not save cache:',err);
|
||||
|
||||
return cb(null, balance);
|
||||
});
|
||||
|
@ -1272,7 +1298,7 @@ WalletService.prototype._getBalanceFromAddresses = function(opts, cb, i) {
|
|||
if (err) return cb(err);
|
||||
|
||||
if (cache) {
|
||||
log.info('Using UTXO Cache');
|
||||
self.logi('Using UTXO Cache');
|
||||
return cb(null, cache, true);
|
||||
}
|
||||
|
||||
|
@ -1313,7 +1339,7 @@ WalletService.prototype._getBalanceOneStep = function(opts, cb) {
|
|||
if (err) return cb(err);
|
||||
|
||||
if (addresses.length == opts.alreadyQueriedLength) {
|
||||
log.info('Query Skipped, all active addresses');
|
||||
self.logi('Query Skipped, all active addresses');
|
||||
return cb(null,null, true);
|
||||
}
|
||||
|
||||
|
@ -1328,7 +1354,7 @@ WalletService.prototype._getBalanceOneStep = function(opts, cb) {
|
|||
var withBalance = _.map(balance.byAddress, 'address')
|
||||
self.storage.storeAddressesWithBalance(self.walletId, withBalance, function(err) {
|
||||
if (err) {
|
||||
log.warn('Could not update wallet cache', err);
|
||||
self.logw('Could not update wallet cache', err);
|
||||
}
|
||||
return cb(null, balance, cacheUsed);
|
||||
});
|
||||
|
@ -1342,7 +1368,7 @@ WalletService.prototype._getActiveAddresses = function(cb) {
|
|||
|
||||
self.storage.fetchAddressesWithBalance(self.walletId, function(err, addressesWB) {
|
||||
if (err) {
|
||||
log.warn('Could not fetch active addresses from cache', err);
|
||||
self.logw('Could not fetch active addresses from cache', err);
|
||||
return cb();
|
||||
}
|
||||
if (!_.isArray(addressesWB))
|
||||
|
@ -1364,7 +1390,7 @@ WalletService.prototype._checkAndUpdateAddressCount = function(twoStepCache, cb)
|
|||
var self = this;
|
||||
|
||||
if (twoStepCache.addressCount > Defaults.TWO_STEP_BALANCE_THRESHOLD) {
|
||||
log.info('Not counting addresses for '+ self.walletId);
|
||||
self.logi('Not counting addresses');
|
||||
return cb(null, true);
|
||||
}
|
||||
|
||||
|
@ -1424,7 +1450,7 @@ WalletService.prototype.getBalance = function(opts, cb, i) {
|
|||
if (!_.isArray(activeAddresses)) {
|
||||
return self._getBalanceOneStep(opts, cb);
|
||||
} else {
|
||||
log.debug('Requesting partial balance for ' + activeAddresses.length + ' addresses');
|
||||
self.logi('Requesting partial balance for ' + activeAddresses.length + ' addresses');
|
||||
|
||||
self._getBalanceFromAddresses({
|
||||
coin: opts.coin,
|
||||
|
@ -1436,13 +1462,13 @@ WalletService.prototype.getBalance = function(opts, cb, i) {
|
|||
var now = Math.floor(Date.now() / 1000);
|
||||
|
||||
if (twoStepCache.lastEmpty > now - Defaults.TWO_STEP_INACTIVE_CLEAN_DURATION_MIN * 60 ) {
|
||||
log.debug('Not running the FULL balance query due to TWO_STEP_INACTIVE_CLEAN_DURATION_MIN ');
|
||||
self.logi('Not running the FULL balance query due to TWO_STEP_INACTIVE_CLEAN_DURATION_MIN ');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
setTimeout(function() {
|
||||
log.debug('Running full balance query');
|
||||
self.logi('Running full balance query');
|
||||
|
||||
opts.alreadyQueriedLength = activeAddresses.length;
|
||||
opts.fastCache = Defaults.BALANCE_CACHE_DURATION;
|
||||
|
@ -1450,7 +1476,7 @@ WalletService.prototype.getBalance = function(opts, cb, i) {
|
|||
self._getBalanceOneStep(opts, function(err, fullBalance, skipped) {
|
||||
if (err) return;
|
||||
if (!skipped && !_.isEqual(partialBalance, fullBalance)) {
|
||||
log.info('Balance in active addresses differs from final balance');
|
||||
self.logi('Balance in active addresses differs from final balance');
|
||||
self._notify('BalanceUpdated', fullBalance, {
|
||||
isGlobal: true
|
||||
});
|
||||
|
@ -1499,7 +1525,6 @@ WalletService.prototype.getSendMaxInfo = function(opts, cb) {
|
|||
return cb(new ClientError('Only one of feeLevel/feePerKb can be specified'));
|
||||
|
||||
if (feeArgs == 0) {
|
||||
log.debug('No fee provided, using "normal" fee level');
|
||||
opts.feeLevel = 'normal';
|
||||
}
|
||||
|
||||
|
@ -1606,7 +1631,7 @@ WalletService.prototype._sampleFeeLevels = function(coin, network, points, cb) {
|
|||
if (!bc) return cb(new Error('Could not get blockchain explorer instance'));
|
||||
bc.estimateFee(points, function(err, result) {
|
||||
if (err) {
|
||||
log.error('Error estimating fee', err);
|
||||
self.logw('Error estimating fee', err);
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
|
@ -1620,7 +1645,7 @@ WalletService.prototype._sampleFeeLevels = function(coin, network, points, cb) {
|
|||
}));
|
||||
|
||||
if (failed.length) {
|
||||
var logger = network == 'livenet' ? log.warn : log.debug;
|
||||
var logger = network == 'livenet' ? self.logw : self.logi;
|
||||
logger('Could not compute fee estimation in ' + network + ': ' + failed.join(', ') + ' blocks.');
|
||||
}
|
||||
|
||||
|
@ -1708,6 +1733,7 @@ WalletService.prototype._estimateFee = function(txp) {
|
|||
};
|
||||
|
||||
WalletService.prototype._checkTx = function(txp) {
|
||||
var self = this;
|
||||
var bitcoreError;
|
||||
|
||||
var serializationOpts = {
|
||||
|
@ -1726,7 +1752,7 @@ WalletService.prototype._checkTx = function(txp) {
|
|||
txp.fee = bitcoreTx.getFee();
|
||||
}
|
||||
} catch (ex) {
|
||||
log.error('Error building Bitcore transaction', ex);
|
||||
self.logw('Error building Bitcore transaction', ex);
|
||||
return ex;
|
||||
}
|
||||
|
||||
|
@ -1782,16 +1808,16 @@ WalletService.prototype._selectTxInputs = function(txp, utxosToExclude, cb) {
|
|||
var netValueInUtxos = totalValueInUtxos - baseTxpFee - (utxos.length * feePerInput);
|
||||
|
||||
if (totalValueInUtxos < txpAmount) {
|
||||
log.debug('Total value in all utxos (' + Utils.formatAmountInBtc(totalValueInUtxos) + ') is insufficient to cover for txp amount (' + Utils.formatAmountInBtc(txpAmount) + ')');
|
||||
self.logi('Total value in all utxos (' + Utils.formatAmountInBtc(totalValueInUtxos) + ') is insufficient to cover for txp amount (' + Utils.formatAmountInBtc(txpAmount) + ')');
|
||||
return cb(Errors.INSUFFICIENT_FUNDS);
|
||||
}
|
||||
if (netValueInUtxos < txpAmount) {
|
||||
log.debug('Value after fees in all utxos (' + Utils.formatAmountInBtc(netValueInUtxos) + ') is insufficient to cover for txp amount (' + Utils.formatAmountInBtc(txpAmount) + ')');
|
||||
self.logi('Value after fees in all utxos (' + Utils.formatAmountInBtc(netValueInUtxos) + ') is insufficient to cover for txp amount (' + Utils.formatAmountInBtc(txpAmount) + ')');
|
||||
return cb(Errors.INSUFFICIENT_FUNDS_FOR_FEE);
|
||||
}
|
||||
|
||||
var bigInputThreshold = txpAmount * Defaults.UTXO_SELECTION_MAX_SINGLE_UTXO_FACTOR + (baseTxpFee + feePerInput);
|
||||
log.debug('Big input threshold ' + Utils.formatAmountInBtc(bigInputThreshold));
|
||||
self.logi('Big input threshold ' + Utils.formatAmountInBtc(bigInputThreshold));
|
||||
|
||||
var partitions = _.partition(utxos, function(utxo) {
|
||||
return utxo.satoshis > bigInputThreshold;
|
||||
|
@ -1802,8 +1828,8 @@ WalletService.prototype._selectTxInputs = function(txp, utxosToExclude, cb) {
|
|||
return -utxo.satoshis;
|
||||
});
|
||||
|
||||
log.debug('Considering ' + bigInputs.length + ' big inputs (' + Utils.formatUtxos(bigInputs) + ')');
|
||||
log.debug('Considering ' + smallInputs.length + ' small inputs (' + Utils.formatUtxos(smallInputs) + ')');
|
||||
//log.debug('Considering ' + bigInputs.length + ' big inputs (' + Utils.formatUtxos(bigInputs) + ')');
|
||||
//log.debug('Considering ' + smallInputs.length + ' small inputs (' + Utils.formatUtxos(smallInputs) + ')');
|
||||
|
||||
var total = 0;
|
||||
var netTotal = -baseTxpFee;
|
||||
|
@ -1812,11 +1838,11 @@ WalletService.prototype._selectTxInputs = function(txp, utxosToExclude, cb) {
|
|||
var error;
|
||||
|
||||
_.each(smallInputs, function(input, i) {
|
||||
log.debug('Input #' + i + ': ' + Utils.formatUtxos(input));
|
||||
//log.debug('Input #' + i + ': ' + Utils.formatUtxos(input));
|
||||
|
||||
var netInputAmount = input.satoshis - feePerInput;
|
||||
|
||||
log.debug('The input contributes ' + Utils.formatAmountInBtc(netInputAmount));
|
||||
//log.debug('The input contributes ' + Utils.formatAmountInBtc(netInputAmount));
|
||||
|
||||
selected.push(input);
|
||||
|
||||
|
@ -1826,45 +1852,45 @@ WalletService.prototype._selectTxInputs = function(txp, utxosToExclude, cb) {
|
|||
var txpSize = baseTxpSize + selected.length * sizePerInput;
|
||||
fee = Math.round(baseTxpFee + selected.length * feePerInput);
|
||||
|
||||
log.debug('Tx size: ' + Utils.formatSize(txpSize) + ', Tx fee: ' + Utils.formatAmountInBtc(fee));
|
||||
//log.debug('Tx size: ' + Utils.formatSize(txpSize) + ', Tx fee: ' + Utils.formatAmountInBtc(fee));
|
||||
|
||||
var feeVsAmountRatio = fee / txpAmount;
|
||||
var amountVsUtxoRatio = netInputAmount / txpAmount;
|
||||
|
||||
log.debug('Fee/Tx amount: ' + Utils.formatRatio(feeVsAmountRatio) + ' (max: ' + Utils.formatRatio(Defaults.UTXO_SELECTION_MAX_FEE_VS_TX_AMOUNT_FACTOR) + ')');
|
||||
log.debug('Tx amount/Input amount:' + Utils.formatRatio(amountVsUtxoRatio) + ' (min: ' + Utils.formatRatio(Defaults.UTXO_SELECTION_MIN_TX_AMOUNT_VS_UTXO_FACTOR) + ')');
|
||||
//log.debug('Fee/Tx amount: ' + Utils.formatRatio(feeVsAmountRatio) + ' (max: ' + Utils.formatRatio(Defaults.UTXO_SELECTION_MAX_FEE_VS_TX_AMOUNT_FACTOR) + ')');
|
||||
//log.debug('Tx amount/Input amount:' + Utils.formatRatio(amountVsUtxoRatio) + ' (min: ' + Utils.formatRatio(Defaults.UTXO_SELECTION_MIN_TX_AMOUNT_VS_UTXO_FACTOR) + ')');
|
||||
|
||||
if (txpSize / 1000. > Defaults.MAX_TX_SIZE_IN_KB) {
|
||||
log.debug('Breaking because tx size (' + Utils.formatSize(txpSize) + ') is too big (max: ' + Utils.formatSize(Defaults.MAX_TX_SIZE_IN_KB * 1000.) + ')');
|
||||
//log.debug('Breaking because tx size (' + Utils.formatSize(txpSize) + ') is too big (max: ' + Utils.formatSize(Defaults.MAX_TX_SIZE_IN_KB * 1000.) + ')');
|
||||
error = Errors.TX_MAX_SIZE_EXCEEDED;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_.isEmpty(bigInputs)) {
|
||||
if (amountVsUtxoRatio < Defaults.UTXO_SELECTION_MIN_TX_AMOUNT_VS_UTXO_FACTOR) {
|
||||
log.debug('Breaking because utxo is too small compared to tx amount');
|
||||
//log.debug('Breaking because utxo is too small compared to tx amount');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (feeVsAmountRatio > Defaults.UTXO_SELECTION_MAX_FEE_VS_TX_AMOUNT_FACTOR) {
|
||||
var feeVsSingleInputFeeRatio = fee / (baseTxpFee + feePerInput);
|
||||
log.debug('Fee/Single-input fee: ' + Utils.formatRatio(feeVsSingleInputFeeRatio) + ' (max: ' + Utils.formatRatio(Defaults.UTXO_SELECTION_MAX_FEE_VS_SINGLE_UTXO_FEE_FACTOR) + ')' + ' loses wrt single-input tx: ' + Utils.formatAmountInBtc((selected.length - 1) * feePerInput));
|
||||
//log.debug('Fee/Single-input fee: ' + Utils.formatRatio(feeVsSingleInputFeeRatio) + ' (max: ' + Utils.formatRatio(Defaults.UTXO_SELECTION_MAX_FEE_VS_SINGLE_UTXO_FEE_FACTOR) + ')' + ' loses wrt single-input tx: ' + Utils.formatAmountInBtc((selected.length - 1) * feePerInput));
|
||||
if (feeVsSingleInputFeeRatio > Defaults.UTXO_SELECTION_MAX_FEE_VS_SINGLE_UTXO_FEE_FACTOR) {
|
||||
log.debug('Breaking because fee is too significant compared to tx amount and it is too expensive compared to using single input');
|
||||
//log.debug('Breaking because fee is too significant compared to tx amount and it is too expensive compared to using single input');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.debug('Cumuled total so far: ' + Utils.formatAmountInBtc(total) + ', Net total so far: ' + Utils.formatAmountInBtc(netTotal));
|
||||
//log.debug('Cumuled total so far: ' + Utils.formatAmountInBtc(total) + ', Net total so far: ' + Utils.formatAmountInBtc(netTotal));
|
||||
|
||||
if (netTotal >= txpAmount) {
|
||||
var changeAmount = Math.round(total - txpAmount - fee);
|
||||
log.debug('Tx change: ', Utils.formatAmountInBtc(changeAmount));
|
||||
//log.debug('Tx change: ', Utils.formatAmountInBtc(changeAmount));
|
||||
|
||||
var dustThreshold = Math.max(Defaults.MIN_OUTPUT_AMOUNT, Bitcore_[txp.coin].Transaction.DUST_AMOUNT);
|
||||
if (changeAmount > 0 && changeAmount <= dustThreshold) {
|
||||
log.debug('Change below dust threshold (' + Utils.formatAmountInBtc(dustThreshold) + '). Incrementing fee to remove change.');
|
||||
//log.debug('Change below dust threshold (' + Utils.formatAmountInBtc(dustThreshold) + '). Incrementing fee to remove change.');
|
||||
// Remove dust change by incrementing fee
|
||||
fee += changeAmount;
|
||||
}
|
||||
|
@ -1874,12 +1900,12 @@ WalletService.prototype._selectTxInputs = function(txp, utxosToExclude, cb) {
|
|||
});
|
||||
|
||||
if (netTotal < txpAmount) {
|
||||
log.debug('Could not reach Txp total (' + Utils.formatAmountInBtc(txpAmount) + '), still missing: ' + Utils.formatAmountInBtc(txpAmount - netTotal));
|
||||
//log.debug('Could not reach Txp total (' + Utils.formatAmountInBtc(txpAmount) + '), still missing: ' + Utils.formatAmountInBtc(txpAmount - netTotal));
|
||||
|
||||
selected = [];
|
||||
if (!_.isEmpty(bigInputs)) {
|
||||
var input = _.first(bigInputs);
|
||||
log.debug('Using big input: ', Utils.formatUtxos(input));
|
||||
//log.debug('Using big input: ', Utils.formatUtxos(input));
|
||||
total = input.satoshis;
|
||||
fee = Math.round(baseTxpFee + feePerInput);
|
||||
netTotal = total - fee;
|
||||
|
@ -1888,14 +1914,14 @@ WalletService.prototype._selectTxInputs = function(txp, utxosToExclude, cb) {
|
|||
}
|
||||
|
||||
if (_.isEmpty(selected)) {
|
||||
log.debug('Could not find enough funds within this utxo subset');
|
||||
//log.debug('Could not find enough funds within this utxo subset');
|
||||
return cb(error || Errors.INSUFFICIENT_FUNDS_FOR_FEE);
|
||||
}
|
||||
|
||||
return cb(null, selected, fee);
|
||||
};
|
||||
|
||||
log.debug('Selecting inputs for a ' + Utils.formatAmountInBtc(txp.getTotalAmount()) + ' txp');
|
||||
//log.debug('Selecting inputs for a ' + Utils.formatAmountInBtc(txp.getTotalAmount()) + ' txp');
|
||||
|
||||
self._getUtxosForCurrentWallet({}, function(err, utxos) {
|
||||
if (err) return cb(err);
|
||||
|
@ -1917,7 +1943,7 @@ WalletService.prototype._selectTxInputs = function(txp, utxosToExclude, cb) {
|
|||
|
||||
utxos = sanitizeUtxos(utxos);
|
||||
|
||||
log.debug('Considering ' + utxos.length + ' utxos (' + Utils.formatUtxos(utxos) + ')');
|
||||
//log.debug('Considering ' + utxos.length + ' utxos (' + Utils.formatUtxos(utxos) + ')');
|
||||
|
||||
var groups = [6, 1];
|
||||
if (!txp.excludeUnconfirmedUtxos) groups.push(0);
|
||||
|
@ -1936,21 +1962,21 @@ WalletService.prototype._selectTxInputs = function(txp, utxosToExclude, cb) {
|
|||
return utxo.confirmations >= group;
|
||||
});
|
||||
|
||||
log.debug('Group >= ' + group);
|
||||
//log.debug('Group >= ' + group);
|
||||
|
||||
// If this group does not have any new elements, skip it
|
||||
if (lastGroupLength === candidateUtxos.length) {
|
||||
log.debug('This group is identical to the one already explored');
|
||||
//log.debug('This group is identical to the one already explored');
|
||||
return next();
|
||||
}
|
||||
|
||||
log.debug('Candidate utxos: ' + Utils.formatUtxos(candidateUtxos));
|
||||
//log.debug('Candidate utxos: ' + Utils.formatUtxos(candidateUtxos));
|
||||
|
||||
lastGroupLength = candidateUtxos.length;
|
||||
|
||||
select(candidateUtxos, function(err, selectedInputs, selectedFee) {
|
||||
if (err) {
|
||||
log.debug('No inputs selected on this group: ', err);
|
||||
//log.debug('No inputs selected on this group: ', err);
|
||||
selectionError = err;
|
||||
return next();
|
||||
}
|
||||
|
@ -1959,8 +1985,8 @@ WalletService.prototype._selectTxInputs = function(txp, utxosToExclude, cb) {
|
|||
inputs = selectedInputs;
|
||||
fee = selectedFee;
|
||||
|
||||
log.debug('Selected inputs from this group: ' + Utils.formatUtxos(inputs));
|
||||
log.debug('Fee for this selection: ' + Utils.formatAmountInBtc(fee));
|
||||
//log.debug('Selected inputs from this group: ' + Utils.formatUtxos(inputs));
|
||||
//log.debug('Fee for this selection: ' + Utils.formatAmountInBtc(fee));
|
||||
|
||||
return next();
|
||||
});
|
||||
|
@ -1975,9 +2001,9 @@ WalletService.prototype._selectTxInputs = function(txp, utxosToExclude, cb) {
|
|||
|
||||
if (!err) {
|
||||
var change = _.sum(txp.inputs, 'satoshis') - _.sum(txp.outputs, 'amount') - txp.fee;
|
||||
log.debug('Successfully built transaction. Total fees: ' + Utils.formatAmountInBtc(txp.fee) + ', total change: ' + Utils.formatAmountInBtc(change));
|
||||
self.logi('Successfully built transaction. Total fees: ' + Utils.formatAmountInBtc(txp.fee) + ', total change: ' + Utils.formatAmountInBtc(change));
|
||||
} else {
|
||||
log.warn('Error building transaction', err);
|
||||
self.logw('Error building transaction', err);
|
||||
}
|
||||
|
||||
return cb(err);
|
||||
|
@ -2008,7 +2034,7 @@ WalletService.prototype._canCreateTx = function(cb) {
|
|||
var backoffTime = Defaults.BACKOFF_TIME;
|
||||
|
||||
if (timeSinceLastRejection <= backoffTime)
|
||||
log.debug('Not allowing to create TX: timeSinceLastRejection/backoffTime', timeSinceLastRejection, backoffTime);
|
||||
self.logi('Not allowing to create TX: timeSinceLastRejection/backoffTime', timeSinceLastRejection, backoffTime);
|
||||
|
||||
return cb(null, timeSinceLastRejection > backoffTime);
|
||||
});
|
||||
|
@ -2061,7 +2087,6 @@ WalletService.prototype._validateAndSanitizeTxOpts = function(wallet, opts, cb)
|
|||
return next(new ClientError('Only one of feeLevel/feePerKb/fee can be specified'));
|
||||
|
||||
if (feeArgs == 0) {
|
||||
log.debug('No fee provided, using "normal" fee level');
|
||||
opts.feeLevel = 'normal';
|
||||
}
|
||||
|
||||
|
@ -2133,7 +2158,7 @@ WalletService.prototype._getFeePerKb = function(wallet, opts, cb) {
|
|||
});
|
||||
if (!level) {
|
||||
var msg = 'Could not compute fee for "' + opts.feeLevel + '" level';
|
||||
log.error(msg);
|
||||
self.logw(msg);
|
||||
return cb(new ClientError(msg));
|
||||
}
|
||||
return cb(null, level.feePerKb);
|
||||
|
@ -2369,7 +2394,7 @@ WalletService.prototype.getTx = function(opts, cb) {
|
|||
|
||||
self.storage.fetchTxNote(self.walletId, txp.txid, function(err, note) {
|
||||
if (err) {
|
||||
log.warn('Error fetching tx note for ' + txp.txid);
|
||||
self.logw('Error fetching tx note for ' + txp.txid);
|
||||
}
|
||||
txp.note = note;
|
||||
return cb(null, txp);
|
||||
|
@ -2572,18 +2597,16 @@ WalletService.prototype.signTx = function(opts, cb) {
|
|||
|
||||
try {
|
||||
if (!txp.sign(self.copayerId, opts.signatures, copayer.xPubKey)) {
|
||||
log.warn('Error signing transaction (BAD_SIGNATURES)');
|
||||
log.warn('Wallet id:', self.walletId);
|
||||
log.warn('Copayer id:', self.copayerId);
|
||||
log.warn('Client version:', self.clientVersion);
|
||||
log.warn('Arguments:', JSON.stringify(opts));
|
||||
log.warn('Transaction proposal:', JSON.stringify(txp));
|
||||
self.logw('Error signing transaction (BAD_SIGNATURES)');
|
||||
self.logw('Client version:', self.clientVersion);
|
||||
self.logw('Arguments:', JSON.stringify(opts));
|
||||
self.logw('Transaction proposal:', JSON.stringify(txp));
|
||||
var raw = txp.getBitcoreTx().uncheckedSerialize();
|
||||
log.warn('Raw tx:', raw);
|
||||
self.logw('Raw tx:', raw);
|
||||
return cb(Errors.BAD_SIGNATURES);
|
||||
}
|
||||
} catch (ex) {
|
||||
log.error('Error signing transaction proposal', ex);
|
||||
self.logw('Error signing transaction proposal', ex);
|
||||
return cb(ex);
|
||||
}
|
||||
|
||||
|
@ -3092,6 +3115,9 @@ WalletService.prototype.getTxHistory = function(opts, cb) {
|
|||
var addressStrs = _.map(addresses, 'address');
|
||||
var bc = self._getBlockchainExplorer(wallet.coin, wallet.network);
|
||||
if (!bc) return next(new Error('Could not get blockchain explorer instance'));
|
||||
|
||||
self.logi('','Querying tx for: %s addrs', addresses.length);
|
||||
|
||||
bc.getTransactions(addressStrs, from, to, function(err, rawTxs, total) {
|
||||
if (err) return next(err);
|
||||
|
||||
|
@ -3149,13 +3175,13 @@ WalletService.prototype.getTxHistory = function(opts, cb) {
|
|||
network: wallet.network
|
||||
}, function(err, levels) {
|
||||
if (err) {
|
||||
log.warn('Could not fetch fee levels', err);
|
||||
self.logw('Could not fetch fee levels', err);
|
||||
} else {
|
||||
var level = _.find(levels, {
|
||||
level: 'superEconomy'
|
||||
});
|
||||
if (!level || !level.nbBlocks) {
|
||||
log.debug('Cannot compute super economy fee level from blockchain');
|
||||
self.logi('Cannot compute super economy fee level from blockchain');
|
||||
} else {
|
||||
var minFeePerKb = level.feePerKb;
|
||||
_.each(unconfirmed, function(tx) {
|
||||
|
@ -3217,10 +3243,10 @@ WalletService.prototype.getTxHistory = function(opts, cb) {
|
|||
|
||||
tagLowFees(wallet, finalTxs, function(err) {
|
||||
if (err)
|
||||
log.warn('Failed to tag unconfirmed with low fee');
|
||||
self.logw('Failed to tag unconfirmed with low fee');
|
||||
|
||||
if (res.txs.fromCache)
|
||||
log.debug("History from cache for:", self.walletId, from, to);
|
||||
self.logi("History from cache for:", self.walletId, from, to);
|
||||
|
||||
return cb(null, finalTxs, !!res.txs.fromCache);
|
||||
});
|
||||
|
@ -3253,7 +3279,7 @@ WalletService.prototype.scan = function(opts, cb) {
|
|||
var gap = Defaults.SCAN_ADDRESS_GAP;
|
||||
|
||||
async.whilst(function() {
|
||||
log.debug('Scanning addr gap:'+ inactiveCounter);
|
||||
self.logi('Scanning addr gap:'+ inactiveCounter);
|
||||
return inactiveCounter < gap;
|
||||
}, function(next) {
|
||||
var address = derivator.derive();
|
||||
|
|
Loading…
Reference in New Issue