diff --git a/Connection.js b/Connection.js index f7078ee84..a50edb50d 100644 --- a/Connection.js +++ b/Connection.js @@ -2,7 +2,7 @@ require('classtool'); function spec(b) { var config = b.config || require('./config'); - var log = b.log || require('./util/log')(config); + var log = b.log || require('./util/log'); var network = b.network || require('./networks')[config.network]; var MAX_RECEIVE_BUFFER = 10000000; @@ -152,18 +152,18 @@ function spec(b) { } break; } - - this.emit(message.command, { - conn: this, - socket: this.socket, - peer: this.peer, - message: message - }); } catch (e) { - log.err('Error while handling message '+message.command+' from ' + + log.err('Error while handling "'+message.command+'" message from ' + this.peer + ':\n' + (e.stack ? e.stack : e.toString())); + return; } + this.emit(message.command, { + conn: this, + socket: this.socket, + peer: this.peer, + message: message + }); }; Connection.prototype.sendPong = function (nonce) { diff --git a/PeerManager.js b/PeerManager.js index e87f21b89..6d9eee7da 100644 --- a/PeerManager.js +++ b/PeerManager.js @@ -2,7 +2,7 @@ require('classtool'); function spec(b) { var config = b.config || require('./config'); - var log = b.log || require('./util/log')(config); + var log = b.log || require('./util/log'); var network = b.network || require('./networks')[config.network]; var Connection = b.Connection || require('./Connection').createClass({config: config}); var Peer = b.Peer || require('./Peer').class(); @@ -166,7 +166,7 @@ function spec(b) { }; PeerManager.prototype.handleError = function(e) { - log.err(e.peer, e.err); + log.err('unkown error with peer '+e.peer+' (disconnecting): '+e.err); this.handleDisconnect.apply(this, [].slice.call(arguments)); }; diff --git a/RpcClient.js b/RpcClient.js index 631c0897c..5add42698 100644 --- a/RpcClient.js +++ b/RpcClient.js @@ -6,7 +6,7 @@ require('classtool'); function ClassSpec(b) { var http = b.http || require('http'); var https = b.https || require('https'); - var log = b.log || {err: function(){}}; + var log = b.log || require('./util/log'); function RpcClient(opts) { opts = opts || {}; @@ -64,7 +64,7 @@ function ClassSpec(b) { help: '', importAddress: 'str str bool', importPrivKey: 'str str bool', - keypoolRefill: '', + keyPoolRefill: '', listAccounts: 'int', listAddressGroupings: '', listReceivedByAccount: 'int bool', @@ -152,12 +152,22 @@ function ClassSpec(b) { options[k] = self.httpOptions[k]; } } + var err = null; var req = this.protocol.request(options, function(res) { + var buf = ''; res.on('data', function(data) { buf += data; }); res.on('end', function() { + if(res.statusCode == 401) { + callback(new Error('bitcoin JSON-RPC connection rejected: unauthorized')); + return; + } + if(err) { + callback(err); + return; + } try { var parsedBuf = JSON.parse(buf); } catch(e) { @@ -170,7 +180,7 @@ function ClassSpec(b) { }); }); req.on('error', function(e) { - callback(e); + log.err('Could not connect to bitcoin via RPC: '+e); }); req.setHeader('Content-Length', request.length); diff --git a/Script.js b/Script.js index fe5912785..58f7605ac 100644 --- a/Script.js +++ b/Script.js @@ -2,7 +2,7 @@ require('classtool'); function spec(b) { var config = b.config || require('./config'); - var log = b.log || require('./util/log')(config); + var log = b.log || require('./util/log'); var Opcode = require('./Opcode').class(); @@ -21,13 +21,13 @@ function spec(b) { var TX_MULTISIG = 3; var TX_SCRIPTHASH = 4; - var TX_TYPES = { - TX_UNKNOWN: 'unknown', - TX_PUBKEY: 'pubkey', - TX_PUBKEYHASH: 'pubkeyhash', - TX_MULTISIG: 'multisig', - TX_SCRIPTHASH: 'scripthash', - }; + var TX_TYPES = [ + 'unknown', + 'pubkey', + 'pubkeyhash', + 'multisig', + 'scripthash' + ]; function Script(buffer) { if(buffer) { @@ -168,12 +168,16 @@ function spec(b) { Script.prototype.getOutType = function () { - var txType = this.classify(); - switch (txType) { - case TX_PUBKEY: return 'Pubkey'; - case TX_PUBKEYHASH: return 'Address'; - default: return 'Strange'; - } + var txType = this.classify(); + switch (txType) { + case TX_PUBKEY: return 'Pubkey'; + case TX_PUBKEYHASH: return 'Address'; + default: return 'Strange'; + } + }; + + Script.prototype.getRawOutType = function() { + return TX_TYPES[this.classify()]; }; Script.prototype.simpleOutHash = function () diff --git a/ScriptInterpreter.js b/ScriptInterpreter.js index 86ffe5c3b..5eeea9471 100644 --- a/ScriptInterpreter.js +++ b/ScriptInterpreter.js @@ -3,7 +3,7 @@ require('classtool'); function spec(b) { var assert = require('assert'); var config = b.config || require('./config'); - var log = b.log || require('./util/log')(config); + var log = b.log || require('./util/log'); var Opcode = require('./Opcode').class(); diff --git a/Transaction.js b/Transaction.js index b96dcef5c..0e20b6c48 100644 --- a/Transaction.js +++ b/Transaction.js @@ -2,7 +2,7 @@ require('classtool'); function spec(b) { var config = b.config || require('./config'); - var log = b.log || require('./util/log')(config); + var log = b.log || require('./util/log'); var Script = b.Script || require('./Script').class(); var ScriptInterpreter = b.ScriptInterpreter || require('./ScriptInterpreter').class(); var util = b.util || require('./util/util'); diff --git a/util/EncodedData.js b/util/EncodedData.js index 7fb2d5383..5c1e87ee5 100644 --- a/util/EncodedData.js +++ b/util/EncodedData.js @@ -57,6 +57,16 @@ function ClassSpec(b) { this._validate(); }; + // Boolean protocol for testing if valid + EncodedData.prototype.isValid = function() { + try { + this.validate(); + return true; + } catch(e) { + return false; + } + }; + // convert to a string (in base58 form) EncodedData.prototype.toString = function() { return this.as('base58'); diff --git a/util/log.js b/util/log.js index 6570b71ae..f2dbce42a 100644 --- a/util/log.js +++ b/util/log.js @@ -6,9 +6,9 @@ var loggers = { debug: {info: console.log, warn: console.log, err: console.log, debug: console.log}, }; -module.exports = function(config) { - config = config || {}; - if(config.log) return config.log; - if(config.loggers) return config.loggers[config.logging || 'normal']; - return loggers[config.logging || 'normal']; -}; +var config = require('../config'); +if(config.log) { + module.exports = config.log; +} else { + module.exports = loggers[config.logger || 'normal']; +} diff --git a/util/util.js b/util/util.js index fe170a16a..b57dfab71 100644 --- a/util/util.js +++ b/util/util.js @@ -3,6 +3,7 @@ var crypto = require('crypto'); var bignum = require('bignum'); var Binary = require('binary'); var Put = require('bufferput'); +var Address = require('../Address').class(); var sha256 = exports.sha256 = function (data) { return new Buffer(crypto.createHash('sha256').update(data).digest('binary'), 'binary'); @@ -107,50 +108,6 @@ var formatValue = exports.formatValue = function (valueBuffer) { return integerPart+"."+decimalPart; }; -var pubKeyHashToAddress = exports.pubKeyHashToAddress = function (pubKeyHash, addressVersion) { - if (!pubKeyHash) return ""; - - var put = new Put(); - // Version - if(addressVersion) { - put.word8le(addressVersion); - } else { - put.word8le(0); - } - // Hash - put.put(pubKeyHash); - // Checksum (four bytes) - put.put(twoSha256(put.buffer()).slice(0,4)); - return encodeBase58(put.buffer()); -}; - -var addressToPubKeyHash = exports.addressToPubKeyHash = function (address) { - // Trim - address = String(address).replace(/\s/g, ''); - - // Check sanity - if (!address.match(/^[1-9A-HJ-NP-Za-km-z]{27,35}$/)) { - return null; - } - - // Decode - var buffer = decodeBase58(address); - - // Parse - var parser = Binary.parse(buffer); - parser.word8('version'); - parser.buffer('hash', 20); - parser.buffer('checksum', 4); - - // Check checksum - var checksum = twoSha256(buffer.slice(0, 21)).slice(0, 4); - if (checksum.compare(parser.vars.checksum) !== 0) { - return null; - } - - return parser.vars.hash; -}; - // Utility that synchronizes function calls based on a key var createSynchrotron = exports.createSynchrotron = function (fn) { var table = {};