From f0223146aff3dac135c4f24752cd5db502ad7717 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sun, 2 Oct 2016 01:01:16 -0700 Subject: [PATCH] deps: massive refactor. --- bench/coin.js | 19 +- bin/cli | 2 +- bin/node | 2 +- bin/spvnode | 2 +- lib/bip70/bip70.js | 592 +------------------------------- lib/bip70/index.js | 3 + lib/bip70/payment.js | 127 +++++++ lib/bip70/paymentack.js | 71 ++++ lib/bip70/paymentdetails.js | 185 ++++++++++ lib/bip70/paymentrequest.js | 252 ++++++++++++++ lib/bip70/protobuf.js | 2 +- lib/chain/chain.js | 2 +- lib/chain/chaindb.js | 2 +- lib/chain/chainentry.js | 4 +- lib/chain/coins.js | 241 +------------ lib/chain/coinview.js | 4 +- lib/chain/compress.js | 240 +++++++++++++ lib/chain/index.js | 10 + lib/crypto/crypto.js | 11 + lib/crypto/ec.js | 2 +- lib/crypto/index.js | 3 + lib/db/index.js | 12 + lib/db/ldb.js | 2 +- lib/db/lowlevelup.js | 2 +- lib/db/rbt.js | 2 +- lib/env.js | 38 +- lib/hd/hd.js | 3 +- lib/hd/index.js | 3 + lib/hd/mnemonic.js | 2 +- lib/hd/private.js | 2 +- lib/hd/public.js | 2 +- lib/http/base.js | 2 +- lib/http/client.js | 2 +- lib/http/index.js | 12 +- lib/http/request.js | 2 +- lib/http/rpc.js | 4 +- lib/http/server.js | 5 +- lib/mempool/fees.js | 17 +- lib/mempool/index.js | 7 + lib/mempool/mempool.js | 224 ++---------- lib/mempool/mempoolentry.js | 191 +++++++++++ lib/miner/index.js | 6 + lib/miner/miner.js | 14 +- lib/miner/minerblock.js | 41 ++- lib/net/bip150.js | 19 +- lib/net/bip151.js | 20 +- lib/net/bip152.js | 29 +- lib/net/framer.js | 7 +- lib/net/index.js | 15 + lib/net/packets.js | 147 ++++---- lib/net/parser.js | 6 +- lib/net/peer.js | 42 ++- lib/net/pool.js | 46 ++- lib/net/proxysocket.js | 5 +- lib/node/config.js | 2 +- lib/node/fullnode.js | 26 +- lib/node/index.js | 9 + lib/node/node.js | 25 +- lib/node/spvnode.js | 15 +- lib/primitives/abstractblock.js | 21 +- lib/primitives/address.js | 4 +- lib/primitives/block.js | 30 +- lib/primitives/coin.js | 35 +- lib/primitives/headers.js | 15 +- lib/primitives/index.js | 19 + lib/primitives/input.js | 30 +- lib/primitives/invitem.js | 9 +- lib/primitives/keyring.js | 62 ++-- lib/primitives/memblock.js | 14 +- lib/primitives/merkleblock.js | 20 +- lib/primitives/mtx.js | 63 ++-- lib/primitives/netaddress.js | 21 +- lib/primitives/outpoint.js | 13 +- lib/primitives/output.js | 21 +- lib/primitives/tx.js | 72 ++-- lib/protocol/index.js | 7 + lib/protocol/network.js | 3 +- lib/script/index.js | 10 + lib/script/opcode.js | 12 +- lib/script/program.js | 7 +- lib/script/script.js | 32 +- lib/script/sigcache.js | 10 +- lib/script/stack.js | 23 +- lib/script/witness.js | 19 +- lib/utils/async.js | 2 +- lib/utils/errors.js | 5 +- lib/utils/index.js | 3 + lib/utils/lazy.js | 18 + lib/utils/locker.js | 2 +- lib/utils/reader.js | 2 +- lib/utils/uri.js | 6 +- lib/utils/utils.js | 37 +- lib/utils/writer.js | 2 +- lib/wallet/account.js | 6 +- lib/wallet/index.js | 10 + lib/wallet/path.js | 4 +- lib/wallet/txdb.js | 2 +- lib/wallet/wallet.js | 2 +- lib/wallet/walletdb.js | 6 +- lib/wallet/walletkey.js | 2 - lib/workers/framer.js | 146 ++++++++ lib/workers/index.js | 9 + lib/workers/jobs.js | 10 +- lib/workers/parser.js | 225 ++++++++++++ lib/workers/workers.js | 339 +----------------- test/bip70-test.js | 2 +- test/http-test.js | 2 +- test/script-test.js | 2 +- vendor/ip.js | 2 +- 109 files changed, 2307 insertions(+), 1895 deletions(-) create mode 100644 lib/bip70/index.js create mode 100644 lib/bip70/payment.js create mode 100644 lib/bip70/paymentack.js create mode 100644 lib/bip70/paymentdetails.js create mode 100644 lib/bip70/paymentrequest.js create mode 100644 lib/chain/compress.js create mode 100644 lib/chain/index.js create mode 100644 lib/crypto/index.js create mode 100644 lib/db/index.js create mode 100644 lib/hd/index.js create mode 100644 lib/mempool/index.js create mode 100644 lib/mempool/mempoolentry.js create mode 100644 lib/miner/index.js create mode 100644 lib/net/index.js create mode 100644 lib/node/index.js create mode 100644 lib/primitives/index.js create mode 100644 lib/protocol/index.js create mode 100644 lib/script/index.js create mode 100644 lib/utils/index.js create mode 100644 lib/utils/lazy.js create mode 100644 lib/wallet/index.js create mode 100644 lib/workers/framer.js create mode 100644 lib/workers/index.js create mode 100644 lib/workers/parser.js diff --git a/bench/coin.js b/bench/coin.js index 2009eca8..f2305104 100644 --- a/bench/coin.js +++ b/bench/coin.js @@ -1,20 +1,19 @@ 'use strict'; var bn = require('bn.js'); -var bcoin = require('../').set('main'); -var constants = bcoin.constants; -var utils = bcoin.utils; +var constants = require('../lib/protocol/constants'); +var utils = require('../lib/utils/utils'); var assert = require('assert'); var scriptTypes = constants.scriptTypes; var bench = require('./bench'); var fs = require('fs'); - -bcoin.cache(); +var Coins = require('../lib/chain/coins'); +var TX = require('../lib/primitives/tx'); var wtx = fs.readFileSync(__dirname + '/../test/data/wtx.hex', 'utf8'); -wtx = bcoin.tx.fromRaw(wtx.trim(), 'hex'); +wtx = tx.fromRaw(wtx.trim(), 'hex'); -var coins = bcoin.coins.fromTX(wtx); +var coins = Coins.fromTX(wtx); var raw; var end = bench('serialize'); @@ -24,16 +23,16 @@ end(i); var end = bench('parse'); for (var i = 0; i < 10000; i++) - bcoin.coins.fromRaw(raw); + Coins.fromRaw(raw); end(i); var end = bench('parse-single'); var hash = wtx.hash('hex'); for (var i = 0; i < 10000; i++) - bcoin.coins.parseCoin(raw, hash, 5); + Coins.parseCoin(raw, hash, 5); end(i); -var coins = bcoin.coins.fromRaw(raw); +var coins = Coins.fromRaw(raw); var end = bench('get'); var j; diff --git a/bin/cli b/bin/cli index 049ba32c..ba565443 100755 --- a/bin/cli +++ b/bin/cli @@ -8,7 +8,7 @@ var spawn = require('../lib/utils/spawn'); var Client = require('../lib/http/client'); var Wallet = require('../lib/http/wallet'); var co = spawn.co; -var assert = utils.assert; +var assert = require('assert'); var main; function CLI() { diff --git a/bin/node b/bin/node index 5550be7a..b8050722 100755 --- a/bin/node +++ b/bin/node @@ -6,7 +6,7 @@ process.title = 'bcoin'; var bcoin = require('../'); var utils = bcoin.utils; -var assert = utils.assert; +var assert = require('assert'); var options = bcoin.config({ config: true, diff --git a/bin/spvnode b/bin/spvnode index a2d3c2fc..a10abc42 100755 --- a/bin/spvnode +++ b/bin/spvnode @@ -6,7 +6,7 @@ process.title = 'bcoin'; var bcoin = require('../'); var utils = bcoin.utils; -var assert = utils.assert; +var assert = require('assert'); var options = bcoin.config({ config: true, diff --git a/lib/bip70/bip70.js b/lib/bip70/bip70.js index bc280cdf..c801f766 100644 --- a/lib/bip70/bip70.js +++ b/lib/bip70/bip70.js @@ -6,586 +6,12 @@ 'use strict'; -var assert = require('assert'); -var utils = require('../utils/utils'); -var crypto = require('../crypto/crypto'); -var Output = require('../primitives/output'); -var TX = require('../primitives/tx'); -var Script = require('../script/script'); -var x509 = require('./x509'); -var asn1 = require('./asn1'); -var protobuf = require('./protobuf'); -var ProtoReader = protobuf.ProtoReader; -var ProtoWriter = protobuf.ProtoWriter; - -function PaymentRequest(options) { - if (!(this instanceof PaymentRequest)) - return new PaymentRequest(options); - - this.version = -1; - this.pkiType = null; - this.pkiData = null; - this.paymentDetails = new PaymentDetails(); - this.signature = null; - - if (options) - this.fromOptions(options); -} - -PaymentRequest.prototype.fromOptions = function fromOptions(options) { - if (options.version != null) { - assert(utils.isNumber(options.version)); - this.version = options.version; - } - - if (options.pkiType != null) { - assert(typeof options.pkiType === 'string'); - this.pkiType = options.pkiType; - } - - if (options.pkiData) { - assert(Buffer.isBuffer(options.pkiData)); - this.pkiData = options.pkiData; - } - - if (options.paymentDetails) - this.paymentDetails.fromOptions(options.paymentDetails); - - if (options.signature) { - assert(Buffer.isBuffer(options.signature)); - this.signature = options.signature; - } - - if (options.chain) - this.setChain(options.chain); - - return this; -}; - -PaymentRequest.fromOptions = function fromOptions(options) { - return new PaymentRequest().fromOptions(options); -}; - -PaymentRequest.prototype.fromRaw = function fromRaw(data) { - var p = new ProtoReader(data); - - this.version = p.readFieldU32(1, true); - this.pkiType = p.readFieldString(2, true); - this.pkiData = p.readFieldBytes(3, true); - this.paymentDetails.fromRaw(p.readFieldBytes(4)); - this.signature = p.readFieldBytes(5, true); - - return this; -}; - -PaymentRequest.fromRaw = function fromRaw(data, enc) { - if (typeof data === 'string') - data = new Buffer(data, enc); - return new PaymentRequest().fromRaw(data); -}; - -PaymentRequest.prototype.toRaw = function toRaw(writer) { - var p = new ProtoWriter(writer); - - if (this.version !== -1) - p.writeFieldU32(1, this.version); - - if (this.pkiType != null) - p.writeFieldString(2, this.pkiType); - - if (this.pkiData) - p.writeFieldBytes(3, this.pkiData); - - p.writeFieldBytes(4, this.paymentDetails.toRaw()); - - if (this.signature) - p.writeFieldBytes(5, this.signature); - - if (!writer) - p = p.render(); - - return p; -}; - -PaymentRequest.prototype.getAlgorithm = function getAlgorithm() { - var parts; - - if (!this.pkiType) - return; - - parts = this.pkiType.split('+'); - - if (parts.length !== 2) - return; - - if (parts[0] !== 'x509') - return; - - if (parts[1] !== 'sha1' && parts[1] !== 'sha256') - return; - - return { key: parts[0], hash: parts[1] }; -}; - -PaymentRequest.prototype.signatureData = function signatureData() { - var signature = this.signature; - var data; - - this.signature = new Buffer(0); - - data = this.toRaw(); - - this.signature = signature; - - return data; -}; - -PaymentRequest.prototype.signatureHash = function signatureHash() { - var alg = this.getAlgorithm(); - assert(alg, 'No hash algorithm available.'); - return crypto.hash(alg.hash, this.signatureData()); -}; - -PaymentRequest.prototype.setChain = function setChain(chain) { - var p = new ProtoWriter(); - var i, cert, pem; - - if (!Array.isArray(chain)) - chain = [chain]; - - for (i = 0; i < chain.length; i++) { - cert = chain[i]; - if (typeof cert === 'string') { - pem = asn1.fromPEM(cert); - assert(pem.type === 'certificate', 'Bad certificate PEM.'); - cert = pem.data; - } - assert(Buffer.isBuffer(cert), 'Certificates must be PEM or DER.'); - p.writeFieldBytes(1, cert); - } - - this.pkiData = p.render(); -}; - -PaymentRequest.prototype.getChain = function getChain() { - var chain = []; - var p; - - if (!this.pkiData) - return chain; - - p = new ProtoReader(this.pkiData); - - while (p.nextTag() === 1) - chain.push(p.readFieldBytes(1)); - - return chain; -}; - -PaymentRequest.prototype.sign = function sign(key, chain) { - var alg, msg; - - if (chain) - this.setChain(chain); - - if (!this.pkiType) - this.pkiType = 'x509+sha256'; - - alg = this.getAlgorithm(); - assert(alg, 'No hash algorithm available.'); - - msg = this.signatureData(); - chain = this.getChain(); - - this.signature = x509.signSubject(alg.hash, msg, key, chain); -}; - -PaymentRequest.prototype.verify = function verify() { - var alg, msg, sig, chain; - - if (!this.pkiType || this.pkiType === 'none') - return true; - - if (!this.signature) - return false; - - alg = this.getAlgorithm(); - - if (!alg) - return false; - - msg = this.signatureData(); - sig = this.signature; - chain = this.getChain(); - - return x509.verifySubject(alg.hash, msg, sig, chain); -}; - -PaymentRequest.prototype.verifyChain = function verifyChain() { - if (!this.pkiType || this.pkiType === 'none') - return true; - - return x509.verifyChain(this.getChain()); -}; - -PaymentRequest.prototype.getCA = function getCA() { - var chain, root; - - if (!this.pkiType || this.pkiType === 'none') - return; - - chain = this.getChain(); - - if (chain.length === 0) - return; - - root = x509.parse(chain[chain.length - 1]); - - if (!root) - return; - - return { - name: x509.getCAName(root), - trusted: x509.isTrusted(root), - cert: root - }; -}; - -function PaymentDetails(options) { - if (!(this instanceof PaymentDetails)) - return new PaymentDetails(options); - - this.network = null; - this.outputs = []; - this.time = utils.now(); - this.expires = -1; - this.memo = null; - this.paymentUrl = null; - this.merchantData = null; - - if (options) - this.fromOptions(options); -} - -PaymentDetails.prototype.fromOptions = function fromOptions(options) { - var i, output; - - if (options.network != null) { - assert(typeof options.network === 'string'); - this.network = options.network; - } - - if (options.outputs) { - assert(Array.isArray(options.outputs)); - for (i = 0; i < options.outputs.length; i++) { - output = new Output(options.outputs[i]); - this.outputs.push(output); - } - } - - if (options.time != null) { - assert(utils.isNumber(options.time)); - this.time = options.time; - } - - if (options.expires != null) { - assert(utils.isNumber(options.expires)); - this.expires = options.expires; - } - - if (options.memo != null) { - assert(typeof options.memo === 'string'); - this.memo = options.memo; - } - - if (options.paymentUrl != null) { - assert(typeof options.paymentUrl === 'string'); - this.paymentUrl = options.paymentUrl; - } - - if (options.merchantData) - this.setData(options.merchantData); - - return this; -}; - -PaymentDetails.fromOptions = function fromOptions(options) { - return new PaymentDetails().fromOptions(options); -}; - -PaymentDetails.prototype.isExpired = function isExpired() { - if (this.expires === -1) - return false; - return utils.now() > this.expires; -}; - -PaymentDetails.prototype.setData = function setData(data, enc) { - if (data == null || Buffer.isBuffer(data)) { - this.merchantData = data; - return; - } - - if (typeof data !== 'string') { - assert(!enc || enc === 'json'); - this.merchantData = new Buffer(JSON.stringify(data), 'utf8'); - return; - } - - this.merchantData = new Buffer(data, enc); -}; - -PaymentDetails.prototype.getData = function getData(enc) { - var data = this.merchantData; - - if (!data) - return; - - if (!enc) - return data; - - if (enc === 'json') { - data = data.toString('utf8'); - try { - data = JSON.parse(data); - } catch (e) { - return; - } - return data; - } - - return data.toString(enc); -}; - -PaymentDetails.prototype.fromRaw = function fromRaw(data) { - var p = new ProtoReader(data); - var op, output; - - this.network = p.readFieldString(1, true); - - while (p.nextTag() === 2) { - op = new ProtoReader(p.readFieldBytes(2)); - output = new Output(); - output.value = op.readFieldU64(1, true); - output.script.fromRaw(op.readFieldBytes(2, true)); - this.outputs.push(output); - } - - this.time = p.readFieldU64(3); - this.expires = p.readFieldU64(4, true); - this.memo = p.readFieldString(5, true); - this.paymentUrl = p.readFieldString(6, true); - this.merchantData = p.readFieldBytes(7, true); - - return this; -}; - -PaymentDetails.fromRaw = function fromRaw(data, enc) { - if (typeof data === 'string') - data = new Buffer(data, enc); - return new PaymentDetails().fromRaw(data); -}; - -PaymentDetails.prototype.toRaw = function toRaw(writer) { - var p = new ProtoWriter(writer); - var i, op, output; - - if (this.network != null) - p.writeFieldString(1, this.network); - - for (i = 0; i < this.outputs.length; i++) { - output = this.outputs[i]; - op = new ProtoWriter(); - op.writeFieldU64(1, output.value); - op.writeFieldBytes(2, output.script.toRaw()); - p.writeFieldBytes(2, op.render()); - } - - p.writeFieldU64(3, this.time); - - if (this.expires !== -1) - p.writeFieldU64(4, this.expires); - - if (this.memo != null) - p.writeFieldString(5, this.memo); - - if (this.paymentUrl != null) - p.writeFieldString(6, this.paymentUrl); - - if (this.merchantData) - p.writeFieldString(7, this.merchantData); - - if (!writer) - p = p.render(); - - return p; -}; - -function Payment(options) { - if (!(this instanceof Payment)) - return new Payment(options); - - this.merchantData = null; - this.transactions = []; - this.refundTo = []; - this.memo = null; - - if (options) - this.fromOptions(options); -} - -Payment.prototype.fromOptions = function fromOptions(options) { - var i, tx, output; - - if (options.merchantData) - this.setData(options.merchantData); - - if (options.transactions) { - assert(Array.isArray(options.transactions)); - for (i = 0; i < options.transactions.length; i++) { - tx = new TX(options.transactions[i]); - this.transactions.push(tx); - } - } - - if (options.refundTo) { - assert(Array.isArray(options.refundTo)); - for (i = 0; i < options.refundTo.length; i++) { - output = new Output(options.refundTo[i]); - this.refundTo.push(output); - } - } - - if (options.memo != null) { - assert(typeof options.memo === 'string'); - this.memo = options.memo; - } - - return this; -}; - -Payment.fromOptions = function fromOptions(options) { - return new Payment().fromOptions(options); -}; - -Payment.prototype.setData = PaymentDetails.prototype.setData; -Payment.prototype.getData = PaymentDetails.prototype.getData; - -Payment.prototype.fromRaw = function fromRaw(data) { - var p = new ProtoReader(data); - var tx, op, output; - - this.merchantData = p.readFieldBytes(1, true); - - while (p.nextTag() === 2) { - tx = TX.fromRaw(p.readFieldBytes(2)); - this.transactions.push(tx); - } - - while (p.nextTag() === 3) { - op = new ProtoReader(p.readFieldBytes(3)); - output = new Output(); - output.value = op.readFieldU64(1, true); - output.script = Script.fromRaw(op.readFieldBytes(2, true)); - this.refundTo.push(output); - } - - this.memo = p.readFieldString(4, true); - - return this; -}; - -Payment.fromRaw = function fromRaw(data, enc) { - if (typeof data === 'string') - data = new Buffer(data, enc); - return new Payment().fromRaw(data); -}; - -Payment.prototype.toRaw = function toRaw(writer) { - var p = new ProtoWriter(writer); - var i, tx, op, output; - - if (this.merchantData) - p.writeFieldBytes(1, this.merchantData); - - for (i = 0; i < this.transactions.length; i++) { - tx = this.transactions[i]; - this.writeFieldBytes(2, tx.toRaw()); - } - - for (i = 0; i < this.refundTo.length; i++) { - op = new ProtoWriter(); - output = this.refundTo[i]; - op.writeFieldU64(1, output.value); - op.writeFieldBytes(2, output.script.toRaw()); - p.writeFieldBytes(3, op.render()); - } - - if (this.memo != null) - p.writeFieldString(4, this.memo); - - if (!writer) - p = p.render(); - - return p; -}; - -function PaymentACK(options) { - if (!(this instanceof PaymentACK)) - return new PaymentACK(options); - - this.payment = new Payment(); - this.memo = null; - - if (options) - this.fromOptions(options); -} - -PaymentACK.prototype.fromOptions = function fromOptions(options) { - if (options.payment) - this.payment.fromOptions(options.payment); - - if (options.memo != null) { - assert(typeof options.memo === 'string'); - this.memo = options.memo; - } - - return this; -}; - -PaymentACK.fromOptions = function fromOptions(options) { - return new PaymentACK().fromOptions(options); -}; - -PaymentACK.prototype.fromRaw = function fromRaw(data) { - var p = new ProtoReader(data); - - this.payment.fromRaw(p.readFieldBytes(1)); - this.memo = p.readFieldString(2, true); - - return this; -}; - -PaymentACK.fromRaw = function fromRaw(data, enc) { - if (typeof data === 'string') - data = new Buffer(data, enc); - return new PaymentACK().fromRaw(data); -}; - -PaymentACK.prototype.toRaw = function toRaw(writer) { - var p = new ProtoWriter(writer); - - p.writeFieldBytes(1, this.payment.toRaw()); - - if (this.memo != null) - p.writeFieldString(2, this.memo); - - if (!writer) - p = p.render(); - - return p; -}; - -exports.PaymentRequest = PaymentRequest; -exports.PaymentDetails = PaymentDetails; -exports.Payment = Payment; -exports.PaymentACK = PaymentACK; +var lazy = require('../utils/lazy')(require, exports); + +lazy('PaymentRequest', './paymentrequest'); +lazy('PaymentDetails', './paymentdetails'); +lazy('Payment', './payment'); +lazy('PaymentACK', './paymentack'); +lazy('asn1', './asn1'); +lazy('x509', './x509'); +lazy('pk', './pk'); diff --git a/lib/bip70/index.js b/lib/bip70/index.js new file mode 100644 index 00000000..5ea10be4 --- /dev/null +++ b/lib/bip70/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./bip70'); diff --git a/lib/bip70/payment.js b/lib/bip70/payment.js new file mode 100644 index 00000000..e539ac1d --- /dev/null +++ b/lib/bip70/payment.js @@ -0,0 +1,127 @@ +/*! + * payment.js - bip70 payment for bcoin + * Copyright (c) 2016, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/bcoin + */ + +'use strict'; + +var assert = require('assert'); +var Output = require('../primitives/output'); +var TX = require('../primitives/tx'); +var Script = require('../script/script'); +var protobuf = require('./protobuf'); +var PaymentDetails = require('./paymentdetails'); +var ProtoReader = protobuf.ProtoReader; +var ProtoWriter = protobuf.ProtoWriter; + +function Payment(options) { + if (!(this instanceof Payment)) + return new Payment(options); + + this.merchantData = null; + this.transactions = []; + this.refundTo = []; + this.memo = null; + + if (options) + this.fromOptions(options); +} + +Payment.prototype.fromOptions = function fromOptions(options) { + var i, tx, output; + + if (options.merchantData) + this.setData(options.merchantData); + + if (options.transactions) { + assert(Array.isArray(options.transactions)); + for (i = 0; i < options.transactions.length; i++) { + tx = new TX(options.transactions[i]); + this.transactions.push(tx); + } + } + + if (options.refundTo) { + assert(Array.isArray(options.refundTo)); + for (i = 0; i < options.refundTo.length; i++) { + output = new Output(options.refundTo[i]); + this.refundTo.push(output); + } + } + + if (options.memo != null) { + assert(typeof options.memo === 'string'); + this.memo = options.memo; + } + + return this; +}; + +Payment.fromOptions = function fromOptions(options) { + return new Payment().fromOptions(options); +}; + +Payment.prototype.setData = PaymentDetails.prototype.setData; +Payment.prototype.getData = PaymentDetails.prototype.getData; + +Payment.prototype.fromRaw = function fromRaw(data) { + var p = new ProtoReader(data); + var tx, op, output; + + this.merchantData = p.readFieldBytes(1, true); + + while (p.nextTag() === 2) { + tx = TX.fromRaw(p.readFieldBytes(2)); + this.transactions.push(tx); + } + + while (p.nextTag() === 3) { + op = new ProtoReader(p.readFieldBytes(3)); + output = new Output(); + output.value = op.readFieldU64(1, true); + output.script = Script.fromRaw(op.readFieldBytes(2, true)); + this.refundTo.push(output); + } + + this.memo = p.readFieldString(4, true); + + return this; +}; + +Payment.fromRaw = function fromRaw(data, enc) { + if (typeof data === 'string') + data = new Buffer(data, enc); + return new Payment().fromRaw(data); +}; + +Payment.prototype.toRaw = function toRaw(writer) { + var p = new ProtoWriter(writer); + var i, tx, op, output; + + if (this.merchantData) + p.writeFieldBytes(1, this.merchantData); + + for (i = 0; i < this.transactions.length; i++) { + tx = this.transactions[i]; + this.writeFieldBytes(2, tx.toRaw()); + } + + for (i = 0; i < this.refundTo.length; i++) { + op = new ProtoWriter(); + output = this.refundTo[i]; + op.writeFieldU64(1, output.value); + op.writeFieldBytes(2, output.script.toRaw()); + p.writeFieldBytes(3, op.render()); + } + + if (this.memo != null) + p.writeFieldString(4, this.memo); + + if (!writer) + p = p.render(); + + return p; +}; + +module.exports = Payment; diff --git a/lib/bip70/paymentack.js b/lib/bip70/paymentack.js new file mode 100644 index 00000000..37a90bfe --- /dev/null +++ b/lib/bip70/paymentack.js @@ -0,0 +1,71 @@ +/*! + * paymentack.js - bip70 paymentack for bcoin + * Copyright (c) 2016, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/bcoin + */ + +'use strict'; + +var assert = require('assert'); +var protobuf = require('./protobuf'); +var Payment = require('./payment'); +var ProtoReader = protobuf.ProtoReader; +var ProtoWriter = protobuf.ProtoWriter; + +function PaymentACK(options) { + if (!(this instanceof PaymentACK)) + return new PaymentACK(options); + + this.payment = new Payment(); + this.memo = null; + + if (options) + this.fromOptions(options); +} + +PaymentACK.prototype.fromOptions = function fromOptions(options) { + if (options.payment) + this.payment.fromOptions(options.payment); + + if (options.memo != null) { + assert(typeof options.memo === 'string'); + this.memo = options.memo; + } + + return this; +}; + +PaymentACK.fromOptions = function fromOptions(options) { + return new PaymentACK().fromOptions(options); +}; + +PaymentACK.prototype.fromRaw = function fromRaw(data) { + var p = new ProtoReader(data); + + this.payment.fromRaw(p.readFieldBytes(1)); + this.memo = p.readFieldString(2, true); + + return this; +}; + +PaymentACK.fromRaw = function fromRaw(data, enc) { + if (typeof data === 'string') + data = new Buffer(data, enc); + return new PaymentACK().fromRaw(data); +}; + +PaymentACK.prototype.toRaw = function toRaw(writer) { + var p = new ProtoWriter(writer); + + p.writeFieldBytes(1, this.payment.toRaw()); + + if (this.memo != null) + p.writeFieldString(2, this.memo); + + if (!writer) + p = p.render(); + + return p; +}; + +module.exports = PaymentACK; diff --git a/lib/bip70/paymentdetails.js b/lib/bip70/paymentdetails.js new file mode 100644 index 00000000..45171f82 --- /dev/null +++ b/lib/bip70/paymentdetails.js @@ -0,0 +1,185 @@ +/*! + * paymentdetails.js - bip70 paymentdetails for bcoin + * Copyright (c) 2016, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/bcoin + */ + +'use strict'; + +var assert = require('assert'); +var utils = require('../utils/utils'); +var Output = require('../primitives/output'); +var protobuf = require('./protobuf'); +var ProtoReader = protobuf.ProtoReader; +var ProtoWriter = protobuf.ProtoWriter; + +function PaymentDetails(options) { + if (!(this instanceof PaymentDetails)) + return new PaymentDetails(options); + + this.network = null; + this.outputs = []; + this.time = utils.now(); + this.expires = -1; + this.memo = null; + this.paymentUrl = null; + this.merchantData = null; + + if (options) + this.fromOptions(options); +} + +PaymentDetails.prototype.fromOptions = function fromOptions(options) { + var i, output; + + if (options.network != null) { + assert(typeof options.network === 'string'); + this.network = options.network; + } + + if (options.outputs) { + assert(Array.isArray(options.outputs)); + for (i = 0; i < options.outputs.length; i++) { + output = new Output(options.outputs[i]); + this.outputs.push(output); + } + } + + if (options.time != null) { + assert(utils.isNumber(options.time)); + this.time = options.time; + } + + if (options.expires != null) { + assert(utils.isNumber(options.expires)); + this.expires = options.expires; + } + + if (options.memo != null) { + assert(typeof options.memo === 'string'); + this.memo = options.memo; + } + + if (options.paymentUrl != null) { + assert(typeof options.paymentUrl === 'string'); + this.paymentUrl = options.paymentUrl; + } + + if (options.merchantData) + this.setData(options.merchantData); + + return this; +}; + +PaymentDetails.fromOptions = function fromOptions(options) { + return new PaymentDetails().fromOptions(options); +}; + +PaymentDetails.prototype.isExpired = function isExpired() { + if (this.expires === -1) + return false; + return utils.now() > this.expires; +}; + +PaymentDetails.prototype.setData = function setData(data, enc) { + if (data == null || Buffer.isBuffer(data)) { + this.merchantData = data; + return; + } + + if (typeof data !== 'string') { + assert(!enc || enc === 'json'); + this.merchantData = new Buffer(JSON.stringify(data), 'utf8'); + return; + } + + this.merchantData = new Buffer(data, enc); +}; + +PaymentDetails.prototype.getData = function getData(enc) { + var data = this.merchantData; + + if (!data) + return; + + if (!enc) + return data; + + if (enc === 'json') { + data = data.toString('utf8'); + try { + data = JSON.parse(data); + } catch (e) { + return; + } + return data; + } + + return data.toString(enc); +}; + +PaymentDetails.prototype.fromRaw = function fromRaw(data) { + var p = new ProtoReader(data); + var op, output; + + this.network = p.readFieldString(1, true); + + while (p.nextTag() === 2) { + op = new ProtoReader(p.readFieldBytes(2)); + output = new Output(); + output.value = op.readFieldU64(1, true); + output.script.fromRaw(op.readFieldBytes(2, true)); + this.outputs.push(output); + } + + this.time = p.readFieldU64(3); + this.expires = p.readFieldU64(4, true); + this.memo = p.readFieldString(5, true); + this.paymentUrl = p.readFieldString(6, true); + this.merchantData = p.readFieldBytes(7, true); + + return this; +}; + +PaymentDetails.fromRaw = function fromRaw(data, enc) { + if (typeof data === 'string') + data = new Buffer(data, enc); + return new PaymentDetails().fromRaw(data); +}; + +PaymentDetails.prototype.toRaw = function toRaw(writer) { + var p = new ProtoWriter(writer); + var i, op, output; + + if (this.network != null) + p.writeFieldString(1, this.network); + + for (i = 0; i < this.outputs.length; i++) { + output = this.outputs[i]; + op = new ProtoWriter(); + op.writeFieldU64(1, output.value); + op.writeFieldBytes(2, output.script.toRaw()); + p.writeFieldBytes(2, op.render()); + } + + p.writeFieldU64(3, this.time); + + if (this.expires !== -1) + p.writeFieldU64(4, this.expires); + + if (this.memo != null) + p.writeFieldString(5, this.memo); + + if (this.paymentUrl != null) + p.writeFieldString(6, this.paymentUrl); + + if (this.merchantData) + p.writeFieldString(7, this.merchantData); + + if (!writer) + p = p.render(); + + return p; +}; + +module.exports = PaymentDetails; diff --git a/lib/bip70/paymentrequest.js b/lib/bip70/paymentrequest.js new file mode 100644 index 00000000..846c6718 --- /dev/null +++ b/lib/bip70/paymentrequest.js @@ -0,0 +1,252 @@ +/*! + * paymentrequest.js - bip70 paymentrequest for bcoin + * Copyright (c) 2016, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/bcoin + */ + +'use strict'; + +var assert = require('assert'); +var utils = require('../utils/utils'); +var crypto = require('../crypto/crypto'); +var x509 = require('./x509'); +var asn1 = require('./asn1'); +var protobuf = require('./protobuf'); +var PaymentDetails = require('./paymentdetails'); +var ProtoReader = protobuf.ProtoReader; +var ProtoWriter = protobuf.ProtoWriter; + +function PaymentRequest(options) { + if (!(this instanceof PaymentRequest)) + return new PaymentRequest(options); + + this.version = -1; + this.pkiType = null; + this.pkiData = null; + this.paymentDetails = new PaymentDetails(); + this.signature = null; + + if (options) + this.fromOptions(options); +} + +PaymentRequest.prototype.fromOptions = function fromOptions(options) { + if (options.version != null) { + assert(utils.isNumber(options.version)); + this.version = options.version; + } + + if (options.pkiType != null) { + assert(typeof options.pkiType === 'string'); + this.pkiType = options.pkiType; + } + + if (options.pkiData) { + assert(Buffer.isBuffer(options.pkiData)); + this.pkiData = options.pkiData; + } + + if (options.paymentDetails) + this.paymentDetails.fromOptions(options.paymentDetails); + + if (options.signature) { + assert(Buffer.isBuffer(options.signature)); + this.signature = options.signature; + } + + if (options.chain) + this.setChain(options.chain); + + return this; +}; + +PaymentRequest.fromOptions = function fromOptions(options) { + return new PaymentRequest().fromOptions(options); +}; + +PaymentRequest.prototype.fromRaw = function fromRaw(data) { + var p = new ProtoReader(data); + + this.version = p.readFieldU32(1, true); + this.pkiType = p.readFieldString(2, true); + this.pkiData = p.readFieldBytes(3, true); + this.paymentDetails.fromRaw(p.readFieldBytes(4)); + this.signature = p.readFieldBytes(5, true); + + return this; +}; + +PaymentRequest.fromRaw = function fromRaw(data, enc) { + if (typeof data === 'string') + data = new Buffer(data, enc); + return new PaymentRequest().fromRaw(data); +}; + +PaymentRequest.prototype.toRaw = function toRaw(writer) { + var p = new ProtoWriter(writer); + + if (this.version !== -1) + p.writeFieldU32(1, this.version); + + if (this.pkiType != null) + p.writeFieldString(2, this.pkiType); + + if (this.pkiData) + p.writeFieldBytes(3, this.pkiData); + + p.writeFieldBytes(4, this.paymentDetails.toRaw()); + + if (this.signature) + p.writeFieldBytes(5, this.signature); + + if (!writer) + p = p.render(); + + return p; +}; + +PaymentRequest.prototype.getAlgorithm = function getAlgorithm() { + var parts; + + if (!this.pkiType) + return; + + parts = this.pkiType.split('+'); + + if (parts.length !== 2) + return; + + if (parts[0] !== 'x509') + return; + + if (parts[1] !== 'sha1' && parts[1] !== 'sha256') + return; + + return { key: parts[0], hash: parts[1] }; +}; + +PaymentRequest.prototype.signatureData = function signatureData() { + var signature = this.signature; + var data; + + this.signature = new Buffer(0); + + data = this.toRaw(); + + this.signature = signature; + + return data; +}; + +PaymentRequest.prototype.signatureHash = function signatureHash() { + var alg = this.getAlgorithm(); + assert(alg, 'No hash algorithm available.'); + return crypto.hash(alg.hash, this.signatureData()); +}; + +PaymentRequest.prototype.setChain = function setChain(chain) { + var p = new ProtoWriter(); + var i, cert, pem; + + if (!Array.isArray(chain)) + chain = [chain]; + + for (i = 0; i < chain.length; i++) { + cert = chain[i]; + if (typeof cert === 'string') { + pem = asn1.fromPEM(cert); + assert(pem.type === 'certificate', 'Bad certificate PEM.'); + cert = pem.data; + } + assert(Buffer.isBuffer(cert), 'Certificates must be PEM or DER.'); + p.writeFieldBytes(1, cert); + } + + this.pkiData = p.render(); +}; + +PaymentRequest.prototype.getChain = function getChain() { + var chain = []; + var p; + + if (!this.pkiData) + return chain; + + p = new ProtoReader(this.pkiData); + + while (p.nextTag() === 1) + chain.push(p.readFieldBytes(1)); + + return chain; +}; + +PaymentRequest.prototype.sign = function sign(key, chain) { + var alg, msg; + + if (chain) + this.setChain(chain); + + if (!this.pkiType) + this.pkiType = 'x509+sha256'; + + alg = this.getAlgorithm(); + assert(alg, 'No hash algorithm available.'); + + msg = this.signatureData(); + chain = this.getChain(); + + this.signature = x509.signSubject(alg.hash, msg, key, chain); +}; + +PaymentRequest.prototype.verify = function verify() { + var alg, msg, sig, chain; + + if (!this.pkiType || this.pkiType === 'none') + return true; + + if (!this.signature) + return false; + + alg = this.getAlgorithm(); + + if (!alg) + return false; + + msg = this.signatureData(); + sig = this.signature; + chain = this.getChain(); + + return x509.verifySubject(alg.hash, msg, sig, chain); +}; + +PaymentRequest.prototype.verifyChain = function verifyChain() { + if (!this.pkiType || this.pkiType === 'none') + return true; + + return x509.verifyChain(this.getChain()); +}; + +PaymentRequest.prototype.getCA = function getCA() { + var chain, root; + + if (!this.pkiType || this.pkiType === 'none') + return; + + chain = this.getChain(); + + if (chain.length === 0) + return; + + root = x509.parse(chain[chain.length - 1]); + + if (!root) + return; + + return { + name: x509.getCAName(root), + trusted: x509.isTrusted(root), + cert: root + }; +}; + +module.exports = PaymentRequest; diff --git a/lib/bip70/protobuf.js b/lib/bip70/protobuf.js index ce5af7f9..6c334585 100644 --- a/lib/bip70/protobuf.js +++ b/lib/bip70/protobuf.js @@ -7,7 +7,7 @@ 'use strict'; var utils = require('../utils/utils'); -var assert = utils.assert; +var assert = require('assert'); var BufferReader = require('../utils/reader'); var BufferWriter = require('../utils/writer'); diff --git a/lib/chain/chain.js b/lib/chain/chain.js index 24d365d3..0a22c4e4 100644 --- a/lib/chain/chain.js +++ b/lib/chain/chain.js @@ -15,7 +15,7 @@ var constants = require('../protocol/constants'); var utils = require('../utils/utils'); var Locker = require('../utils/locker'); var ChainEntry = require('./chainentry'); -var assert = utils.assert; +var assert = require('assert'); var VerifyError = require('../utils/errors').VerifyError; var VerifyResult = utils.VerifyResult; var time = require('../net/timedata'); diff --git a/lib/chain/chaindb.js b/lib/chain/chaindb.js index b1cb12bc..f5af5ea2 100644 --- a/lib/chain/chaindb.js +++ b/lib/chain/chaindb.js @@ -10,7 +10,7 @@ var AsyncObject = require('../utils/async'); var constants = require('../protocol/constants'); var utils = require('../utils/utils'); -var assert = utils.assert; +var assert = require('assert'); var DUMMY = new Buffer([0]); var BufferWriter = require('../utils/writer'); var BufferReader = require('../utils/reader'); diff --git a/lib/chain/chainentry.js b/lib/chain/chainentry.js index 2ca956af..905c0ab3 100644 --- a/lib/chain/chainentry.js +++ b/lib/chain/chainentry.js @@ -12,10 +12,10 @@ var Network = require('../protocol/network'); var constants = require('../protocol/constants'); var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; +var assert = require('assert'); var BufferWriter = require('../utils/writer'); var BufferReader = require('../utils/reader'); -var Header = require('../primitives/headers'); +var Headers = require('../primitives/headers'); var InvItem = require('../primitives/invitem'); var spawn = require('../utils/spawn'); var co = spawn.co; diff --git a/lib/chain/coins.js b/lib/chain/coins.js index 2e734e50..dd733c09 100644 --- a/lib/chain/coins.js +++ b/lib/chain/coins.js @@ -1,6 +1,5 @@ /*! * coins.js - coins object for bcoin - * Copyright (c) 2014-2015, Fedor Indutny (MIT License) * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License). * https://github.com/bcoin-org/bcoin */ @@ -8,12 +7,14 @@ 'use strict'; var utils = require('../utils/utils'); -var assert = utils.assert; +var assert = require('assert'); var constants = require('../protocol/constants'); var Coin = require('../primitives/coin'); -var ec = require('../crypto/ec'); var BufferReader = require('../utils/reader'); var BufferWriter = require('../utils/writer'); +var compressor = require('./compress'); +var compress = compressor.compress; +var decompress = compressor.decompress; /** * Represents the outputs for a single transaction. @@ -281,7 +282,7 @@ Coins.prototype.toRaw = function toRaw(writer) { continue; } - compressScript(output.script, p); + compress.script(output.script, p); p.writeVarint(output.value); } @@ -516,7 +517,7 @@ CompressedCoin.prototype.toCoin = function toCoin(coins, index) { // Seek to the coin's offset. p.seek(this.offset); - decompressScript(p, coin.script); + decompress.script(p, coin.script); coin.value = p.readVarint(); @@ -533,236 +534,8 @@ CompressedCoin.prototype.toRaw = function toRaw() { return this.raw.slice(this.offset, this.offset + this.size); }; -/* - * Compression - */ - -/** - * Compress a script, write directly to the buffer. - * @param {Script} script - * @param {BufferWriter} p - */ - -function compressScript(script, p) { - var prefix = 0; - var data; - - // Attempt to compress the output scripts. - // We can _only_ ever compress them if - // they are serialized as minimaldata, as - // we need to recreate them when we read - // them. - if (script.isPubkeyhash(true)) { - prefix = 1; - data = script.code[2].data; - } else if (script.isScripthash()) { - prefix = 2; - data = script.code[1].data; - } else if (script.isPubkey(true)) { - prefix = 3; - data = script.code[0].data; - - // Try to compress the key. - data = compressKey(data); - - // If we can't compress it, - // just store the script. - if (!data) - prefix = 0; - } - - p.writeU8(prefix); - - if (prefix === 0) - p.writeVarBytes(script.toRaw()); - else - p.writeBytes(data); -} - -/** - * Decompress a script from buffer reader. - * @param {BufferReader} p - * @param {Script} script - */ - -function decompressScript(p, script) { - var key; - - // Decompress the script. - switch (p.readU8()) { - case 0: - script.fromRaw(p.readVarBytes()); - break; - case 1: - script.fromPubkeyhash(p.readBytes(20)); - break; - case 2: - script.fromScripthash(p.readBytes(20)); - break; - case 3: - // Decompress the key. If this fails, - // we have database corruption! - key = decompressKey(p.readBytes(33)); - script.fromPubkey(key); - break; - default: - throw new Error('Bad prefix.'); - } -} - -/** - * Compress value using an exponent. Takes advantage of - * the fact that many bitcoin values are divisible by 10. - * @see https://github.com/btcsuite/btcd/blob/master/blockchain/compress.go - * @param {Amount} value - * @returns {Number} - */ - -function compressValue(value) { - var exp, last; - - if (value === 0) - return 0; - - exp = 0; - while (value % 10 === 0 && exp < 9) { - value /= 10; - exp++; - } - - if (exp < 9) { - last = value % 10; - value = (value - last) / 10; - return 1 + 10 * (9 * value + last - 1) + exp; - } - - return 10 + 10 * (value - 1); -} - -/** - * Decompress value. - * @param {Number} value - Compressed value. - * @returns {Amount} value - */ - -function decompressValue(value) { - var exp, n, last; - - if (value === 0) - return 0; - - value--; - - exp = value % 10; - value = (value - exp) / 10; - - if (exp < 9) { - last = value % 9; - value = (value - last) / 9; - n = value * 10 + last + 1; - } else { - n = value + 1; - } - - while (exp > 0) { - n *= 10; - exp--; - } - - return n; -} - -/** - * Compress a public key to coins compression format. - * @param {Buffer} key - * @returns {Buffer} - */ - -function compressKey(key) { - var out; - - // We can't compress it if it's not valid. - if (!ec.publicKeyVerify(key)) - return; - - switch (key[0]) { - case 0x02: - case 0x03: - // Key is already compressed. - out = key; - break; - case 0x04: - case 0x06: - case 0x07: - // Compress the key normally. - out = ec.publicKeyConvert(key, true); - // Store the original format (which - // may be a hybrid byte) in the hi - // 3 bits so we can restore it later. - // The hi bits being set also lets us - // know that this key was originally - // decompressed. - out[0] |= key[0] << 2; - break; - default: - throw new Error('Bad point format.'); - } - - assert(out.length === 33); - - return out; -} - -/** - * Decompress a public key from the coins compression format. - * @param {Buffer} key - * @returns {Buffer} - */ - -function decompressKey(key) { - var format = key[0] >>> 2; - var out; - - assert(key.length === 33); - - // Hi bits are not set. This key - // is not meant to be decompressed. - if (format === 0) - return key; - - // Decompress the key, and off the - // low bits so publicKeyConvert - // actually understands it. - key[0] &= 0x03; - out = ec.publicKeyConvert(key, false); - - // Reset the hi bits so as not to - // mutate the original buffer. - key[0] |= format << 2; - - // Set the original format, which - // may have been a hybrid prefix byte. - out[0] = format; - - return out; -} - /* * Expose */ -exports = Coins; - -exports.compress = { - script: compressScript, - value: compressValue, - key: compressKey -}; - -exports.decompress = { - script: decompressScript, - value: decompressValue, - key: decompressKey -}; - -module.exports = exports; +module.exports = Coins; diff --git a/lib/chain/coinview.js b/lib/chain/coinview.js index 0c2dd8ae..a7cb371f 100644 --- a/lib/chain/coinview.js +++ b/lib/chain/coinview.js @@ -1,14 +1,12 @@ /*! * coinview.js - coinview object for bcoin - * Copyright (c) 2014-2015, Fedor Indutny (MIT License) * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License). * https://github.com/bcoin-org/bcoin */ 'use strict'; -var utils = require('../utils/utils'); -var assert = utils.assert; +var assert = require('assert'); var Coins = require('./coins'); /** diff --git a/lib/chain/compress.js b/lib/chain/compress.js new file mode 100644 index 00000000..963fc8fe --- /dev/null +++ b/lib/chain/compress.js @@ -0,0 +1,240 @@ +/*! + * compress.js - coin compressor for bcoin + * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/bcoin + */ + +'use strict'; + +var assert = require('assert'); +var ec = require('../crypto/ec'); + +/* + * Compression + */ + +/** + * Compress a script, write directly to the buffer. + * @param {Script} script + * @param {BufferWriter} p + */ + +function compressScript(script, p) { + var prefix = 0; + var data; + + // Attempt to compress the output scripts. + // We can _only_ ever compress them if + // they are serialized as minimaldata, as + // we need to recreate them when we read + // them. + if (script.isPubkeyhash(true)) { + prefix = 1; + data = script.code[2].data; + } else if (script.isScripthash()) { + prefix = 2; + data = script.code[1].data; + } else if (script.isPubkey(true)) { + prefix = 3; + data = script.code[0].data; + + // Try to compress the key. + data = compressKey(data); + + // If we can't compress it, + // just store the script. + if (!data) + prefix = 0; + } + + p.writeU8(prefix); + + if (prefix === 0) + p.writeVarBytes(script.toRaw()); + else + p.writeBytes(data); +} + +/** + * Decompress a script from buffer reader. + * @param {BufferReader} p + * @param {Script} script + */ + +function decompressScript(p, script) { + var key; + + // Decompress the script. + switch (p.readU8()) { + case 0: + script.fromRaw(p.readVarBytes()); + break; + case 1: + script.fromPubkeyhash(p.readBytes(20)); + break; + case 2: + script.fromScripthash(p.readBytes(20)); + break; + case 3: + // Decompress the key. If this fails, + // we have database corruption! + key = decompressKey(p.readBytes(33)); + script.fromPubkey(key); + break; + default: + throw new Error('Bad prefix.'); + } +} + +/** + * Compress value using an exponent. Takes advantage of + * the fact that many bitcoin values are divisible by 10. + * @see https://github.com/btcsuite/btcd/blob/master/blockchain/compress.go + * @param {Amount} value + * @returns {Number} + */ + +function compressValue(value) { + var exp, last; + + if (value === 0) + return 0; + + exp = 0; + while (value % 10 === 0 && exp < 9) { + value /= 10; + exp++; + } + + if (exp < 9) { + last = value % 10; + value = (value - last) / 10; + return 1 + 10 * (9 * value + last - 1) + exp; + } + + return 10 + 10 * (value - 1); +} + +/** + * Decompress value. + * @param {Number} value - Compressed value. + * @returns {Amount} value + */ + +function decompressValue(value) { + var exp, n, last; + + if (value === 0) + return 0; + + value--; + + exp = value % 10; + value = (value - exp) / 10; + + if (exp < 9) { + last = value % 9; + value = (value - last) / 9; + n = value * 10 + last + 1; + } else { + n = value + 1; + } + + while (exp > 0) { + n *= 10; + exp--; + } + + return n; +} + +/** + * Compress a public key to coins compression format. + * @param {Buffer} key + * @returns {Buffer} + */ + +function compressKey(key) { + var out; + + // We can't compress it if it's not valid. + if (!ec.publicKeyVerify(key)) + return; + + switch (key[0]) { + case 0x02: + case 0x03: + // Key is already compressed. + out = key; + break; + case 0x04: + case 0x06: + case 0x07: + // Compress the key normally. + out = ec.publicKeyConvert(key, true); + // Store the original format (which + // may be a hybrid byte) in the hi + // 3 bits so we can restore it later. + // The hi bits being set also lets us + // know that this key was originally + // decompressed. + out[0] |= key[0] << 2; + break; + default: + throw new Error('Bad point format.'); + } + + assert(out.length === 33); + + return out; +} + +/** + * Decompress a public key from the coins compression format. + * @param {Buffer} key + * @returns {Buffer} + */ + +function decompressKey(key) { + var format = key[0] >>> 2; + var out; + + assert(key.length === 33); + + // Hi bits are not set. This key + // is not meant to be decompressed. + if (format === 0) + return key; + + // Decompress the key, and off the + // low bits so publicKeyConvert + // actually understands it. + key[0] &= 0x03; + out = ec.publicKeyConvert(key, false); + + // Reset the hi bits so as not to + // mutate the original buffer. + key[0] |= format << 2; + + // Set the original format, which + // may have been a hybrid prefix byte. + out[0] = format; + + return out; +} + +/* + * Expose + */ + +exports.compress = { + script: compressScript, + value: compressValue, + key: compressKey +}; + +exports.decompress = { + script: decompressScript, + value: decompressValue, + key: decompressKey +}; diff --git a/lib/chain/index.js b/lib/chain/index.js new file mode 100644 index 00000000..3eac4bce --- /dev/null +++ b/lib/chain/index.js @@ -0,0 +1,10 @@ +'use strict'; + +var lazy = require('../utils/lazy')(require, exports); + +lazy('Chain', './chain'); +lazy('ChainDB', './chaindb'); +lazy('ChainEntry', './chainentry'); +lazy('Coins', './coins'); +lazy('CoinView', './coinview'); +lazy('compressor', './compress'); diff --git a/lib/crypto/crypto.js b/lib/crypto/crypto.js index de3dcf24..4146a6db 100644 --- a/lib/crypto/crypto.js +++ b/lib/crypto/crypto.js @@ -16,6 +16,7 @@ var spawn = require('../utils/spawn'); var co = spawn.co; var wrap = spawn.wrap; var native = require('../utils/native'); +var lazy = require('../utils/lazy')(require, exports); var nodeCrypto, hash, aes; var isBrowser = @@ -641,3 +642,13 @@ crypto.randomRange = random.randomRange; */ crypto.randomInt = random.randomInt; + +/* + * Expose other objects. + */ + +lazy('aes', './aes'); +lazy('chachapoly', './chachapoly'); +lazy('ec', './ec'); +lazy('schnorr', './schnorr'); +lazy('siphash', './siphash'); diff --git a/lib/crypto/ec.js b/lib/crypto/ec.js index 723387d8..2727b303 100644 --- a/lib/crypto/ec.js +++ b/lib/crypto/ec.js @@ -11,7 +11,7 @@ var elliptic = require('elliptic'); var bn = require('bn.js'); var utils = require('../utils/utils'); var crypto = require('./crypto'); -var assert = utils.assert; +var assert = require('assert'); var secp256k1; try { diff --git a/lib/crypto/index.js b/lib/crypto/index.js new file mode 100644 index 00000000..7959f4cc --- /dev/null +++ b/lib/crypto/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./crypto'); diff --git a/lib/db/index.js b/lib/db/index.js new file mode 100644 index 00000000..d2aae7a0 --- /dev/null +++ b/lib/db/index.js @@ -0,0 +1,12 @@ +'use strict'; + +var utils = require('../utils/utils'); +var lazy = require('../utils/lazy')(require, exports); + +lazy('ldb', './ldb'); + +if (utils.isBrowser) + lazy('level', './level'); + +lazy('LowlevelUp', './lowlevelup'); +lazy('RBT', './rbt'); diff --git a/lib/db/ldb.js b/lib/db/ldb.js index 5376893b..6bdd8970 100644 --- a/lib/db/ldb.js +++ b/lib/db/ldb.js @@ -11,7 +11,7 @@ var LowlevelUp = require('./lowlevelup'); var utils = require('../utils/utils'); -var assert = utils.assert; +var assert = require('assert'); /** * @param {Object} options diff --git a/lib/db/lowlevelup.js b/lib/db/lowlevelup.js index 0f190ff1..cd94d65a 100644 --- a/lib/db/lowlevelup.js +++ b/lib/db/lowlevelup.js @@ -8,7 +8,7 @@ 'use strict'; var utils = require('../utils/utils'); -var assert = utils.assert; +var assert = require('assert'); var AsyncObject = require('../utils/async'); var spawn = require('../utils/spawn'); var co = spawn.co; diff --git a/lib/db/rbt.js b/lib/db/rbt.js index 7903a679..a1c5ae95 100644 --- a/lib/db/rbt.js +++ b/lib/db/rbt.js @@ -7,7 +7,7 @@ 'use strict'; var utils = require('../utils/utils'); -var assert = utils.assert; +var assert = require('assert'); var DUMMY = new Buffer([0]); var RED = 0; var BLACK = 1; diff --git a/lib/env.js b/lib/env.js index cae2e47a..e870c553 100644 --- a/lib/env.js +++ b/lib/env.js @@ -7,9 +7,6 @@ 'use strict'; -var utils = require('./utils/utils'); -var global = utils.global; - /** * A BCoin "environment" which is used for * bootstrapping the initial `bcoin` module. @@ -131,9 +128,6 @@ function Environment() { // Crypto this.require('ec', './crypto/ec'); this.require('crypto', './crypto/crypto'); - this.require('chachapoly', './crypto/chachapoly'); - this.require('scrypt', './crypto/scrypt'); - this.require('siphash', './crypto/siphash'); // DB this.require('lowlevelup', './db/lowlevelup'); @@ -146,7 +140,6 @@ function Environment() { this.require('stack', './script/stack'); this.require('witness', './script/witness'); this.require('program', './script/program'); - this.require('sigcache', './script/sigcache'); // Primitives this.require('address', './primitives/address'); @@ -157,8 +150,6 @@ function Environment() { this.require('invitem', './primitives/invitem'); this.require('tx', './primitives/tx'); this.require('mtx', './primitives/mtx'); - this.require('abstractblock', './primitives/abstractblock'); - this.require('memblock', './primitives/memblock'); this.require('block', './primitives/block'); this.require('merkleblock', './primitives/merkleblock'); this.require('headers', './primitives/headers'); @@ -185,8 +176,6 @@ function Environment() { this.require('pool', './net/pool'); // Chain - this.require('coins', './chain/coins'); - this.require('coinview', './chain/coinview'); this.require('chainentry', './chain/chainentry'); this.require('chaindb', './chain/chaindb'); this.require('chain', './chain/chain'); @@ -194,7 +183,7 @@ function Environment() { // Mempool this.require('fees', './mempool/fees'); this.require('mempool', './mempool/mempool'); - this.expose('mempoolentry', 'mempool', 'MempoolEntry'); + this.require('mempoolentry', './mempool/mempoolentry'); // Miner this.require('miner', './miner/miner'); @@ -205,6 +194,7 @@ function Environment() { this.require('account', './wallet/account'); this.require('walletdb', './wallet/walletdb'); this.require('path', './wallet/path'); + this.require('walletkey', './wallet/walletkey'); // HTTP this.require('http', './http'); @@ -215,10 +205,6 @@ function Environment() { // Horrible BIP this.require('bip70', './bip70/bip70'); - - // Global Instances - this.expose('defaultLogger', 'logger', 'global'); - this.expose('workerPool', 'workers', 'global'); } /** @@ -236,22 +222,6 @@ Environment.prototype.require = function _require(key, path) { }); }; -/** - * Assign a property for a lazily required module. - * @param {String} key - * @param {String} object - * @param {String} property - */ - -Environment.prototype.expose = function expose(key, object, property) { - var cache; - this.__defineGetter__(key, function() { - if (!cache) - cache = this[object][property]; - return cache; - }); -}; - /** * Set the default network. * @param {String} options @@ -370,12 +340,8 @@ Environment.prototype.cache = function cache() { */ exports.require = Environment.prototype.require; -exports.expose = Environment.prototype.expose; -exports.instance = Environment.prototype.instance; exports.cache = Environment.prototype.cache; exports.set = Environment.prototype.set; exports.now = Environment.prototype.now; Environment.call(exports); - -utils.fastProp(exports); diff --git a/lib/hd/hd.js b/lib/hd/hd.js index 3b9382f1..388abb95 100644 --- a/lib/hd/hd.js +++ b/lib/hd/hd.js @@ -6,8 +6,7 @@ 'use strict'; -var utils = require('../utils/utils'); -var assert = utils.assert; +var assert = require('assert'); var constants = require('../protocol/constants'); var LRU = require('../utils/lru'); var Mnemonic = require('./mnemonic'); diff --git a/lib/hd/index.js b/lib/hd/index.js new file mode 100644 index 00000000..02675b8e --- /dev/null +++ b/lib/hd/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./hd'); diff --git a/lib/hd/mnemonic.js b/lib/hd/mnemonic.js index 7e008061..165a223c 100644 --- a/lib/hd/mnemonic.js +++ b/lib/hd/mnemonic.js @@ -8,7 +8,7 @@ var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; +var assert = require('assert'); var constants = require('../protocol/constants'); var BufferWriter = require('../utils/writer'); var BufferReader = require('../utils/reader'); diff --git a/lib/hd/private.js b/lib/hd/private.js index 543090d2..b9632209 100644 --- a/lib/hd/private.js +++ b/lib/hd/private.js @@ -9,7 +9,7 @@ var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); var ec = require('../crypto/ec'); -var assert = utils.assert; +var assert = require('assert'); var constants = require('../protocol/constants'); var networks = require('../protocol/networks'); var Network = require('../protocol/network'); diff --git a/lib/hd/public.js b/lib/hd/public.js index 91ac05e5..171adadb 100644 --- a/lib/hd/public.js +++ b/lib/hd/public.js @@ -9,7 +9,7 @@ var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); var ec = require('../crypto/ec'); -var assert = utils.assert; +var assert = require('assert'); var constants = require('../protocol/constants'); var networks = require('../protocol/networks'); var Network = require('../protocol/network'); diff --git a/lib/http/base.js b/lib/http/base.js index 29ff9413..beb2b345 100644 --- a/lib/http/base.js +++ b/lib/http/base.js @@ -9,7 +9,7 @@ var AsyncObject = require('../utils/async'); var utils = require('../utils/utils'); -var assert = utils.assert; +var assert = require('assert'); /** * HTTPBase diff --git a/lib/http/client.js b/lib/http/client.js index 5b71ab8f..fe53a944 100644 --- a/lib/http/client.js +++ b/lib/http/client.js @@ -13,7 +13,7 @@ var RPCClient = require('./rpcclient'); var utils = require('../utils/utils'); var spawn = require('../utils/spawn'); var co = spawn.co; -var assert = utils.assert; +var assert = require('assert'); var request = require('./request').promise; /** diff --git a/lib/http/index.js b/lib/http/index.js index 124f1f60..6ea938c8 100644 --- a/lib/http/index.js +++ b/lib/http/index.js @@ -8,11 +8,13 @@ 'use strict'; var utils = require('../utils/utils'); +var lazy = require('../utils/lazy')(require, exports); if (!utils.isBrowser) { - exports.request = require('./request'); - exports.client = require('./client'); - exports.wallet = require('./wallet'); - exports.base = require('./base'); - exports.server = require('./server'); + lazy('request', './request'); + lazy('Client', './client'); + lazy('RPCClient', './rpcclient'); + lazy('Wallet', './wallet'); + lazy('Base', './base'); + lazy('Server', './server'); } diff --git a/lib/http/request.js b/lib/http/request.js index 4a7dbefa..59fe4c36 100644 --- a/lib/http/request.js +++ b/lib/http/request.js @@ -14,7 +14,7 @@ */ var Stream = require('stream').Stream; -var assert = require('../utils/utils').assert; +var assert = require('assert'); // Spoof by default var USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1)' diff --git a/lib/http/rpc.js b/lib/http/rpc.js index 5722c162..f06c5454 100644 --- a/lib/http/rpc.js +++ b/lib/http/rpc.js @@ -10,7 +10,7 @@ var utils = require('../utils/utils'); var spawn = require('../utils/spawn'); var co = spawn.co; var crypto = require('../crypto/crypto'); -var assert = utils.assert; +var assert = require('assert'); var constants = require('../protocol/constants'); var ec = require('../crypto/ec'); var time = require('../net/timedata'); @@ -376,7 +376,7 @@ RPC.prototype.getnetworkinfo = function getnetworkinfo(args) { subversion: constants.USER_AGENT, protocolversion: constants.VERSION, localservices: this.pool.services, - timeoffset: Time.offset, + timeoffset: time.offset, connections: this.pool.peers.all.length, networks: [], relayfee: +utils.btc(this.network.getMinRelay()), diff --git a/lib/http/server.js b/lib/http/server.js index 2cd72e0a..16dce34b 100644 --- a/lib/http/server.js +++ b/lib/http/server.js @@ -11,8 +11,7 @@ var EventEmitter = require('events').EventEmitter; var constants = require('../protocol/constants'); -var http = require('./'); -var HTTPBase = http.base; +var HTTPBase = require('./base'); var utils = require('../utils/utils'); var spawn = require('../utils/spawn'); var Address = require('../primitives/address'); @@ -21,7 +20,7 @@ var Script = require('../script/script'); var co = spawn.co; var con = spawn.con; var crypto = require('../crypto/crypto'); -var assert = utils.assert; +var assert = require('assert'); var RPC; /*= require('./rpc'); - load lazily */ /** diff --git a/lib/mempool/fees.js b/lib/mempool/fees.js index d5d2f852..bc3436ab 100644 --- a/lib/mempool/fees.js +++ b/lib/mempool/fees.js @@ -8,13 +8,14 @@ 'use strict'; -var bcoin = require('../env'); -var utils = bcoin.utils; +var utils = require('../utils/utils'); var assert = require('assert'); -var constants = bcoin.constants; +var constants = require('../protocol/constants'); var BufferReader = require('../utils/reader'); var BufferWriter = require('../utils/writer'); -var global = bcoin.utils.global; +var Logger = require('../node/logger'); +var Network = require('../protocol/network'); +var global = utils.global; var Float64Array = global.Float64Array || Array; var Int32Array = global.Int32Array || Array; @@ -54,7 +55,7 @@ function ConfirmStats(buckets, maxConfirms, decay, type, logger) { if (!(this instanceof ConfirmStats)) return new ConfirmStats(buckets, maxConfirms, decay, type, logger); - this.logger = logger || bcoin.defaultLogger; + this.logger = logger || Logger.global; this.maxConfirms = maxConfirms; this.decay = decay; this.type = type; @@ -399,8 +400,8 @@ function PolicyEstimator(minRelay, network, logger) { fee = []; priority = []; - this.network = bcoin.network.get(network); - this.logger = logger || bcoin.defaultLogger; + this.network = Network.get(network); + this.logger = logger || Logger.global; this.minTrackedFee = minRelay < MIN_FEERATE ? MIN_FEERATE @@ -776,7 +777,7 @@ PolicyEstimator.prototype.toRaw = function toRaw(writer) { PolicyEstimator.fromRaw = function fromRaw(minRelay, data, logger) { var p = new BufferReader(data); - var network = bcoin.network.fromMagic(p.readU32()); + var network = Network.fromMagic(p.readU32()); var bestHeight = p.readU32(); var estimator = new PolicyEstimator(minRelay, network, logger); var feeStats = ConfirmStats.fromRaw(p.readVarBytes(), 'FeeRate', logger); diff --git a/lib/mempool/index.js b/lib/mempool/index.js new file mode 100644 index 00000000..97aa6521 --- /dev/null +++ b/lib/mempool/index.js @@ -0,0 +1,7 @@ +'use strict'; + +var lazy = require('../utils/lazy')(require, exports); + +lazy('Mempool', './mempool'); +lazy('MempoolEntry', './mempoolentry'); +lazy('Fees', './fees'); diff --git a/lib/mempool/mempool.js b/lib/mempool/mempool.js index 9ba87138..d25167b6 100644 --- a/lib/mempool/mempool.js +++ b/lib/mempool/mempool.js @@ -1,25 +1,28 @@ /*! * mempool.js - mempool for bcoin - * Copyright (c) 2014-2015, Fedor Indutny (MIT License) * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License). * https://github.com/bcoin-org/bcoin */ 'use strict'; -var bcoin = require('../env'); var AsyncObject = require('../utils/async'); -var constants = bcoin.constants; +var constants = require('../protocol/constants'); var utils = require('../utils/utils'); var spawn = require('../utils/spawn'); var co = spawn.co; -var assert = utils.assert; -var BufferWriter = require('../utils/writer'); -var BufferReader = require('../utils/reader'); +var assert = require('assert'); var crypto = require('../crypto/crypto'); -var VerifyError = bcoin.errors.VerifyError; +var VerifyError = require('../utils/errors').VerifyError; var VerifyResult = utils.VerifyResult; var flags = constants.flags; +var Bloom = require('../utils/bloom'); +var Address = require('../primitives/address'); +var Coin = require('../primitives/coin'); +var Locker = require('../utils/locker'); +var Outpoint = require('../primitives/outpoint'); +var TX = require('../primitives/tx'); +var MempoolEntry = require('./mempoolentry'); /** * Represents a mempool. @@ -75,7 +78,7 @@ function Mempool(options) { this.logger = options.logger || this.chain.logger; this.loaded = false; - this.locker = new bcoin.locker(true); + this.locker = new Locker(true); this.size = 0; this.totalOrphans = 0; @@ -89,7 +92,7 @@ function Mempool(options) { this.coinIndex = new AddressIndex(this); this.txIndex = new AddressIndex(this); - this.rejects = new bcoin.bloom.rolling(120000, 0.000001); + this.rejects = new Bloom.rolling(120000, 0.000001); this.freeCount = 0; this.lastTime = 0; @@ -366,7 +369,7 @@ Mempool.prototype.getCoin = function getCoin(hash, index) { if (index >= entry.tx.outputs.length) return; - return bcoin.coin.fromTX(entry.tx, index); + return Coin.fromTX(entry.tx, index); }; /** @@ -397,7 +400,7 @@ Mempool.prototype.getCoinsByAddress = function getCoinsByAddress(addresses) { addresses = [addresses]; for (i = 0; i < addresses.length; i++) { - hash = bcoin.address.getHash(addresses[i], 'hex'); + hash = Address.getHash(addresses[i], 'hex'); if (!hash) continue; @@ -425,7 +428,7 @@ Mempool.prototype.getTXByAddress = function getTXByAddress(addresses) { addresses = [addresses]; for (i = 0; i < addresses.length; i++) { - hash = bcoin.address.getHash(addresses[i], 'hex'); + hash = Address.getHash(addresses[i], 'hex'); if (!hash) continue; @@ -465,7 +468,7 @@ Mempool.prototype.fillHistory = function fillHistory(tx) { if (!prev) continue; - input.coin = bcoin.coin.fromTX(prev, prevout.index); + input.coin = Coin.fromTX(prev, prevout.index); } }; @@ -796,7 +799,7 @@ Mempool.prototype.removeUnchecked = function removeUnchecked(entry, limit) { if (limit) { this.logger.spam('Removed tx %s from mempool.', entry.tx.rhash); - rate = bcoin.tx.getRate(entry.sizes, entry.fees); + rate = TX.getRate(entry.sizes, entry.fees); rate += this.minReasonable; if (rate > this.minRate) { this.minRate = rate; @@ -1318,7 +1321,7 @@ Mempool.prototype.getOrphan = function getOrphan(hash) { return; try { - orphan = bcoin.tx.fromExtended(data, true); + orphan = TX.fromExtended(data, true); } catch (e) { delete this.orphans[hash]; this.logger.warning('%s %s', @@ -1530,7 +1533,7 @@ Mempool.prototype.isDoubleSpend = function isDoubleSpend(tx) { Mempool.prototype.getConfidence = co(function* getConfidence(hash) { var tx, result; - if (hash instanceof bcoin.tx) { + if (hash instanceof TX) { tx = hash; hash = hash.hash('hex'); } else { @@ -1595,7 +1598,7 @@ Mempool.prototype.trackEntry = function trackEntry(entry) { if (output.script.isUnspendable()) continue; - coin = bcoin.coin.fromTX(tx, i); + coin = Coin.fromTX(tx, i); this.coinIndex.addCoin(coin); } } @@ -1639,7 +1642,7 @@ Mempool.prototype.untrackEntry = function untrackEntry(entry) { if (output.script.isUnspendable()) continue; - coin = bcoin.coin.fromTX(tx, i); + coin = Coin.fromTX(tx, i); this.coinIndex.removeCoin(coin); } } @@ -1765,180 +1768,6 @@ Mempool.prototype.getSize = function getSize() { return this.size; }; -/** - * Represents a mempool entry. - * @exports MempoolEntry - * @constructor - * @param {Object} options - * @param {TX} options.tx - Transaction in mempool. - * @param {Number} options.height - Entry height. - * @param {Number} options.priority - Entry priority. - * @param {Number} options.ts - Entry time. - * @param {Amount} options.chainValue - Value of on-chain coins. - * @param {Number} options.count - Number of descendants (includes tx). - * @param {Number} options.size - TX and descendant modified size. - * @param {Amount} options.fees - TX and descendant delta-applied fees. - * @property {TX} tx - * @property {Number} height - * @property {Number} priority - * @property {Number} ts - * @property {Amount} chainValue - * @property {Number} count - * @property {Number} size - * @property {Amount} fees - */ - -function MempoolEntry(options) { - if (!(this instanceof MempoolEntry)) - return new MempoolEntry(options); - - this.tx = null; - this.height = -1; - this.size = 0; - this.priority = 0; - this.fee = 0; - this.ts = 0; - - this.chainValue = 0; - this.count = 0; - this.sizes = 0; - this.fees = 0; - this.dependencies = false; - - if (options) - this.fromOptions(options); -} - -/** - * Inject properties from options object. - * @private - * @param {Object} options - */ - -MempoolEntry.prototype.fromOptions = function fromOptions(options) { - this.tx = options.tx; - this.height = options.height; - this.size = options.size; - this.priority = options.priority; - this.fee = options.fee; - this.ts = options.ts; - - this.chainValue = options.chainValue; - this.count = options.count; - this.sizes = options.sizes; - this.fees = options.fees; - this.dependencies = options.dependencies; - - return this; -}; - -/** - * Instantiate mempool entry from options. - * @param {Object} options - * @returns {MempoolEntry} - */ - -MempoolEntry.fromOptions = function fromOptions(options) { - return new MempoolEntry().fromOptions(options); -}; - -/** - * Inject properties from transaction. - * @private - * @param {TX} tx - * @param {Number} height - */ - -MempoolEntry.prototype.fromTX = function fromTX(tx, height) { - var priority = tx.getPriority(height); - var value = tx.getChainValue(height); - var dependencies = false; - var size = tx.getVirtualSize(); - var fee = tx.getFee(); - var i; - - for (i = 0; i < tx.inputs.length; i++) { - if (tx.inputs[i].coin.height === -1) { - dependencies = true; - break; - } - } - - this.tx = tx; - this.height = height; - this.size = size; - this.priority = priority; - this.fee = fee; - this.chainValue = value; - this.ts = utils.now(); - this.count = 1; - this.sizes = size; - this.fees = fee; - this.dependencies = dependencies; - - return this; -}; - -/** - * Create a mempool entry from a TX. - * @param {TX} tx - * @param {Number} height - Entry height. - * @returns {MempoolEntry} - */ - -MempoolEntry.fromTX = function fromTX(tx, height) { - return new MempoolEntry().fromTX(tx, height); -}; - -/** - * Calculate priority, taking into account - * the entry height delta, modified size, - * and chain value. - * @param {Number} height - * @returns {Number} Priority. - */ - -MempoolEntry.prototype.getPriority = function getPriority(height) { - var heightDelta = height - this.height; - var modSize = this.tx.getModifiedSize(this.size); - var deltaPriority = (heightDelta * this.chainValue) / modSize; - var result = this.priority + Math.floor(deltaPriority); - if (result < 0) - result = 0; - return result; -}; - -/** - * Get fee. - * @returns {Amount} - */ - -MempoolEntry.prototype.getFee = function getFee() { - return this.fee; -}; - -/** - * Calculate fee rate. - * @returns {Rate} - */ - -MempoolEntry.prototype.getRate = function getRate() { - return bcoin.tx.getRate(this.size, this.fee); -}; - -/** - * Test whether the entry is free with - * the current priority (calculated by - * current height). - * @param {Number} height - * @returns {Boolean} - */ - -MempoolEntry.prototype.isFree = function isFree(height) { - var priority = this.getPriority(height); - return priority > constants.tx.FREE_THRESHOLD; -}; - /** * Address Index */ @@ -1958,7 +1787,7 @@ AddressIndex.prototype.getCoins = function getCoins(address) { for (i = 0; i < items.length; i++) { item = items[i]; - outpoint = bcoin.outpoint.fromRaw(item); + outpoint = Outpoint.fromRaw(item); coin = this.mempool.getCoin(outpoint.hash, outpoint.index); assert(coin); out.push(coin); @@ -2044,7 +1873,7 @@ AddressIndex.prototype.addCoin = function addCoin(coin) { this.map[hash] = items; } - outpoint = bcoin.outpoint(coin.hash, coin.index).toRaw(); + outpoint = Outpoint(coin.hash, coin.index).toRaw(); utils.binaryInsert(items, outpoint, utils.cmp); this.map[key] = hash; @@ -2063,7 +1892,7 @@ AddressIndex.prototype.removeCoin = function removeCoin(coin) { if (!items) return; - outpoint = bcoin.outpoint(coin.hash, coin.index).toRaw(); + outpoint = Outpoint(coin.hash, coin.index).toRaw(); utils.binaryRemove(items, outpoint, utils.cmp); if (items.length === 0) @@ -2076,7 +1905,4 @@ AddressIndex.prototype.removeCoin = function removeCoin(coin) { * Expose */ -exports = Mempool; -exports.MempoolEntry = MempoolEntry; - -module.exports = exports; +module.exports = Mempool; diff --git a/lib/mempool/mempoolentry.js b/lib/mempool/mempoolentry.js new file mode 100644 index 00000000..d2ee2efa --- /dev/null +++ b/lib/mempool/mempoolentry.js @@ -0,0 +1,191 @@ +/*! + * mempoolentry.js - mempool entry object for bcoin + * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/bcoin + */ + +'use strict'; + +var constants = require('../protocol/constants'); +var utils = require('../utils/utils'); +var TX = require('../primitives/tx'); + +/** + * Represents a mempool entry. + * @exports MempoolEntry + * @constructor + * @param {Object} options + * @param {TX} options.tx - Transaction in mempool. + * @param {Number} options.height - Entry height. + * @param {Number} options.priority - Entry priority. + * @param {Number} options.ts - Entry time. + * @param {Amount} options.chainValue - Value of on-chain coins. + * @param {Number} options.count - Number of descendants (includes tx). + * @param {Number} options.size - TX and descendant modified size. + * @param {Amount} options.fees - TX and descendant delta-applied fees. + * @property {TX} tx + * @property {Number} height + * @property {Number} priority + * @property {Number} ts + * @property {Amount} chainValue + * @property {Number} count + * @property {Number} size + * @property {Amount} fees + */ + +function MempoolEntry(options) { + if (!(this instanceof MempoolEntry)) + return new MempoolEntry(options); + + this.tx = null; + this.height = -1; + this.size = 0; + this.priority = 0; + this.fee = 0; + this.ts = 0; + + this.chainValue = 0; + this.count = 0; + this.sizes = 0; + this.fees = 0; + this.dependencies = false; + + if (options) + this.fromOptions(options); +} + +/** + * Inject properties from options object. + * @private + * @param {Object} options + */ + +MempoolEntry.prototype.fromOptions = function fromOptions(options) { + this.tx = options.tx; + this.height = options.height; + this.size = options.size; + this.priority = options.priority; + this.fee = options.fee; + this.ts = options.ts; + + this.chainValue = options.chainValue; + this.count = options.count; + this.sizes = options.sizes; + this.fees = options.fees; + this.dependencies = options.dependencies; + + return this; +}; + +/** + * Instantiate mempool entry from options. + * @param {Object} options + * @returns {MempoolEntry} + */ + +MempoolEntry.fromOptions = function fromOptions(options) { + return new MempoolEntry().fromOptions(options); +}; + +/** + * Inject properties from transaction. + * @private + * @param {TX} tx + * @param {Number} height + */ + +MempoolEntry.prototype.fromTX = function fromTX(tx, height) { + var priority = tx.getPriority(height); + var value = tx.getChainValue(height); + var dependencies = false; + var size = tx.getVirtualSize(); + var fee = tx.getFee(); + var i; + + for (i = 0; i < tx.inputs.length; i++) { + if (tx.inputs[i].coin.height === -1) { + dependencies = true; + break; + } + } + + this.tx = tx; + this.height = height; + this.size = size; + this.priority = priority; + this.fee = fee; + this.chainValue = value; + this.ts = utils.now(); + this.count = 1; + this.sizes = size; + this.fees = fee; + this.dependencies = dependencies; + + return this; +}; + +/** + * Create a mempool entry from a TX. + * @param {TX} tx + * @param {Number} height - Entry height. + * @returns {MempoolEntry} + */ + +MempoolEntry.fromTX = function fromTX(tx, height) { + return new MempoolEntry().fromTX(tx, height); +}; + +/** + * Calculate priority, taking into account + * the entry height delta, modified size, + * and chain value. + * @param {Number} height + * @returns {Number} Priority. + */ + +MempoolEntry.prototype.getPriority = function getPriority(height) { + var heightDelta = height - this.height; + var modSize = this.tx.getModifiedSize(this.size); + var deltaPriority = (heightDelta * this.chainValue) / modSize; + var result = this.priority + Math.floor(deltaPriority); + if (result < 0) + result = 0; + return result; +}; + +/** + * Get fee. + * @returns {Amount} + */ + +MempoolEntry.prototype.getFee = function getFee() { + return this.fee; +}; + +/** + * Calculate fee rate. + * @returns {Rate} + */ + +MempoolEntry.prototype.getRate = function getRate() { + return TX.getRate(this.size, this.fee); +}; + +/** + * Test whether the entry is free with + * the current priority (calculated by + * current height). + * @param {Number} height + * @returns {Boolean} + */ + +MempoolEntry.prototype.isFree = function isFree(height) { + var priority = this.getPriority(height); + return priority > constants.tx.FREE_THRESHOLD; +}; + +/* + * Expose + */ + +module.exports = MempoolEntry; diff --git a/lib/miner/index.js b/lib/miner/index.js new file mode 100644 index 00000000..d888e015 --- /dev/null +++ b/lib/miner/index.js @@ -0,0 +1,6 @@ +'use strict'; + +var lazy = require('../utils/lazy')(require, exports); + +lazy('Miner', './miner'); +lazy('MinerBlock', './minerblock'); diff --git a/lib/miner/miner.js b/lib/miner/miner.js index 8bd64f55..b8878fbd 100644 --- a/lib/miner/miner.js +++ b/lib/miner/miner.js @@ -7,13 +7,15 @@ 'use strict'; -var bcoin = require('../env'); var utils = require('../utils/utils'); var spawn = require('../utils/spawn'); var co = spawn.co; -var assert = utils.assert; +var assert = require('assert'); var AsyncObject = require('../utils/async'); var MinerBlock = require('./minerblock'); +var Address = require('../primitives/address'); +var Workers = require('../workers/workers'); +var time = require('../net/timedata'); /** * A bitcoin miner (supports mining witness blocks). @@ -38,7 +40,7 @@ function Miner(options) { options = {}; this.options = options; - this.address = bcoin.address(this.options.address); + this.address = Address(this.options.address); this.coinbaseFlags = this.options.coinbaseFlags || 'mined by bcoin'; this.version = null; @@ -113,8 +115,8 @@ Miner.prototype._init = function _init() { stat.best); }); - if (bcoin.workers.enabled) { - this.workerPool = new bcoin.workers({ + if (Workers.enabled) { + this.workerPool = new Workers({ size: 1, timeout: -1 }); @@ -248,7 +250,7 @@ Miner.prototype.createBlock = co(function* createBlock(tip) { assert(tip); - ts = Math.max(bcoin.now(), tip.ts + 1); + ts = Math.max(time.now(), tip.ts + 1); // Find target target = yield this.chain.getTargetAsync(ts, tip); diff --git a/lib/miner/minerblock.js b/lib/miner/minerblock.js index 8a2e0a6c..846c009d 100644 --- a/lib/miner/minerblock.js +++ b/lib/miner/minerblock.js @@ -7,17 +7,24 @@ 'use strict'; -var bcoin = require('../env'); var utils = require('../utils/utils'); var spawn = require('../utils/spawn'); var co = spawn.co; var crypto = require('../crypto/crypto'); -var assert = utils.assert; -var constants = bcoin.constants; +var assert = require('assert'); +var constants = require('../protocol/constants'); +var Network = require('../protocol/network'); var bn = require('bn.js'); var EventEmitter = require('events').EventEmitter; var BufferReader = require('../utils/reader'); var BufferWriter = require('../utils/writer'); +var TX = require('../primitives/tx'); +var Address = require('../primitives/address'); +var Block = require('../primitives/block'); +var Input = require('../primitives/input'); +var Output = require('../primitives/output'); +var time = require('../net/timedata'); +var ChainEntry = require('../chain/chainentry'); /** * MinerBlock @@ -55,16 +62,16 @@ function MinerBlock(options) { this.coinbaseFlags = options.coinbaseFlags; this.witness = options.witness; this.address = options.address; - this.network = bcoin.network.get(options.network); + this.network = Network.get(options.network); this.timeout = null; if (typeof this.coinbaseFlags === 'string') this.coinbaseFlags = new Buffer(this.coinbaseFlags, 'utf8'); - this.coinbase = new bcoin.tx(); + this.coinbase = new TX(); this.coinbase.mutable = true; - this.block = new bcoin.block(); + this.block = new Block(); this.block.mutable = true; this._init(); @@ -84,7 +91,7 @@ MinerBlock.prototype._init = function _init() { var i, input, output, hash, witnessNonce; // Coinbase input. - input = new bcoin.input(); + input = new Input(); // Height (required in v2+ blocks) input.script.set(0, new bn(this.height)); @@ -109,7 +116,7 @@ MinerBlock.prototype._init = function _init() { cb.inputs.push(input); // Reward output. - output = new bcoin.output(); + output = new Output(); output.script.fromAddress(this.address); cb.outputs.push(output); @@ -127,14 +134,14 @@ MinerBlock.prototype._init = function _init() { input.witness.compile(); // Commitment output. - cb.outputs.push(new bcoin.output()); + cb.outputs.push(new Output()); } // Setup our block. block.version = options.version; block.prevBlock = this.tip.hash; block.merkleRoot = constants.NULL_HASH; - block.ts = Math.max(bcoin.now(), this.tip.ts + 1); + block.ts = Math.max(time.now(), this.tip.ts + 1); block.bits = this.bits; block.nonce = 0; block.height = this.height; @@ -191,7 +198,7 @@ MinerBlock.prototype.updateCoinbase = function updateCoinbase() { */ MinerBlock.prototype.updateNonce = function updateNonce() { - this.block.ts = Math.max(bcoin.now(), this.tip.ts + 1); + this.block.ts = Math.max(time.now(), this.tip.ts + 1); // Overflow the nonce and increment the extraNonce. this.block.nonce = 0; @@ -217,7 +224,7 @@ MinerBlock.prototype.updateMerkle = function updateMerkle() { this.updateCommitment(); // Update timestamp. - this.block.ts = Math.max(bcoin.now(), this.tip.ts + 1); + this.block.ts = Math.max(time.now(), this.tip.ts + 1); // Recalculate merkle root. this.block.merkleRoot = this.block.getMerkleRoot('hex'); @@ -307,7 +314,7 @@ MinerBlock.prototype.findNonce = function findNonce() { // update the timestamp. This improves // performance because we do not have to // recalculate the merkle root. - now = bcoin.now(); + now = time.now(); if (now > block.ts && now > tip.ts) { block.ts = now; // Overflow the nonce @@ -452,11 +459,11 @@ MinerBlock.prototype.toRaw = function toRaw(writer) { MinerBlock.fromRaw = function fromRaw(data) { var p = new BufferReader(data); - var network = bcoin.network.fromMagic(p.readU32()); - var tip = bcoin.chainentry.fromRaw(null, p); + var network = Network.fromMagic(p.readU32()); + var tip = ChainEntry.fromRaw(null, p); var version = p.readU32(); var bits = p.readU32(); - var address = bcoin.address.fromRaw(p.readVarBytes()); + var address = Address.fromRaw(p.readVarBytes()); var coinbaseFlags = p.readVarBytes(); var witness = p.readU8() === 1; var count = p.readVarint(); @@ -464,7 +471,7 @@ MinerBlock.fromRaw = function fromRaw(data) { var i; for (i = 0; i < count; i++) - txs.push(bcoin.tx.fromRaw(p)); + txs.push(TX.fromRaw(p)); tip.network = network; diff --git a/lib/net/bip150.js b/lib/net/bip150.js index 63dd2220..75987fc7 100644 --- a/lib/net/bip150.js +++ b/lib/net/bip150.js @@ -9,13 +9,14 @@ 'use strict'; var EventEmitter = require('events').EventEmitter; -var bcoin = require('../env'); var utils = require('../utils/utils'); var spawn = require('../utils/spawn'); var crypto = require('../crypto/crypto'); var packets = require('./packets'); -var assert = utils.assert; -var constants = bcoin.constants; +var assert = require('assert'); +var constants = require('../protocol/constants'); +var ec = require('../crypto/ec'); +var BufferWriter = require('../utils/writer'); /** * Represents a BIP150 input and output stream. @@ -55,7 +56,7 @@ function BIP150(bip151, hostname, outbound, db, identity) { // Identity keypair this.privateKey = identity; - this.publicKey = bcoin.ec.publicKeyCreate(identity, true); + this.publicKey = ec.publicKeyCreate(identity, true); this.challengeReceived = false; this.replyReceived = false; @@ -96,10 +97,10 @@ BIP150.prototype.challenge = function challenge(hash) { this.emit('auth'); } - sig = bcoin.ec.sign(msg, this.privateKey); + sig = ec.sign(msg, this.privateKey); // authreply - return bcoin.ec.fromDER(sig); + return ec.fromDER(sig); }; BIP150.prototype.reply = function reply(data) { @@ -116,10 +117,10 @@ BIP150.prototype.reply = function reply(data) { if (!this.peerIdentity) return crypto.randomBytes(32); - sig = bcoin.ec.toDER(data); + sig = ec.toDER(data); msg = this.hash(this.output.sid, type, this.peerIdentity); - result = bcoin.ec.verify(msg, sig, this.peerIdentity); + result = ec.verify(msg, sig, this.peerIdentity); if (!result) return crypto.randomBytes(32); @@ -280,7 +281,7 @@ BIP150.prototype.getAddress = function getAddress() { }; BIP150.address = function address(key) { - var p = new bcoin.writer(); + var p = new BufferWriter(); p.writeU8(0x0f); p.writeU16BE(0xff01); p.writeBytes(crypto.hash160(key)); diff --git a/lib/net/bip151.js b/lib/net/bip151.js index 0ccdd435..4bad33d2 100644 --- a/lib/net/bip151.js +++ b/lib/net/bip151.js @@ -13,14 +13,16 @@ 'use strict'; var EventEmitter = require('events').EventEmitter; -var bcoin = require('../env'); var utils = require('../utils/utils'); var spawn = require('../utils/spawn'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; -var constants = bcoin.constants; +var assert = require('assert'); +var constants = require('../protocol/constants'); var chachapoly = require('../crypto/chachapoly'); var packets = require('./packets'); +var ec = require('../crypto/ec'); +var BufferWriter = require('../utils/writer'); +var BufferReader = require('../utils/reader'); var EncinitPacket = packets.EncinitPacket; var EncackPacket = packets.EncackPacket; @@ -59,7 +61,7 @@ function BIP151Stream(cipher) { return new BIP151Stream(cipher); this.cipher = cipher || 0; - this.privateKey = bcoin.ec.generatePrivateKey(); + this.privateKey = ec.generatePrivateKey(); this.publicKey = null; this.secret = null; this.prk = null; @@ -87,10 +89,10 @@ function BIP151Stream(cipher) { */ BIP151Stream.prototype.init = function init(publicKey) { - var p = bcoin.writer(); + var p = new BufferWriter(); this.publicKey = publicKey; - this.secret = bcoin.ec.ecdh(this.publicKey, this.privateKey); + this.secret = ec.ecdh(this.publicKey, this.privateKey); p.writeBytes(this.secret); p.writeU8(this.cipher); @@ -200,7 +202,7 @@ BIP151Stream.prototype.update = function update() { */ BIP151Stream.prototype.getPublicKey = function getPublicKey() { - return bcoin.ec.publicKeyCreate(this.privateKey, true); + return ec.publicKeyCreate(this.privateKey, true); }; /** @@ -523,7 +525,7 @@ BIP151.prototype.maybeRekey = function maybeRekey(data) { */ BIP151.prototype.packet = function packet(cmd, body) { - var p = bcoin.writer(); + var p = new BufferWriter(); var payload, packet; p.writeVarString(cmd, 'ascii'); @@ -665,7 +667,7 @@ BIP151.prototype.parse = function parse(data) { this.input.decrypt(payload); this.input.sequence(); - p = bcoin.reader(payload); + p = new BufferReader(payload); while (p.left()) { try { diff --git a/lib/net/bip152.js b/lib/net/bip152.js index 20d16d64..67161c30 100644 --- a/lib/net/bip152.js +++ b/lib/net/bip152.js @@ -6,14 +6,17 @@ 'use strict'; -var bcoin = require('../env'); var utils = require('../utils/utils'); +var BufferReader = require('../utils/reader'); +var BufferWriter = require('../utils/writer'); var spawn = require('../utils/spawn'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; -var constants = bcoin.constants; +var assert = require('assert'); +var constants = require('../protocol/constants'); var siphash = require('../crypto/siphash'); -var AbstractBlock = bcoin.abstractblock; +var AbstractBlock = require('../primitives/abstractblock'); +var TX = require('../primitives/tx'); +var Block = require('../primitives/block'); /** * Represents a compact block (bip152): `cmpctblock` packet. @@ -83,7 +86,7 @@ CompactBlock.fromOptions = function fromOptions(options) { }; CompactBlock.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = new BufferReader(data); var i, count, index, tx; this.version = p.readU32(); // Technically signed @@ -112,7 +115,7 @@ CompactBlock.prototype.fromRaw = function fromRaw(data) { index = p.readVarint(); assert(index <= 0xffff); assert(index < this.totalTX); - tx = bcoin.tx.fromRaw(p); + tx = TX.fromRaw(p); this.ptx.push([index, tx]); } @@ -136,7 +139,7 @@ CompactBlock.prototype.toNormal = function toNormal(writer) { }; CompactBlock.prototype.frame = function frame(witness, writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var i, id, lo, hi, ptx; p.write32(this.version); @@ -308,7 +311,7 @@ CompactBlock.prototype.init = function init() { }; CompactBlock.prototype.toBlock = function toBlock() { - var block = new bcoin.block(); + var block = new Block(); var i, tx; block.version = this.version; @@ -443,7 +446,7 @@ TXRequest.fromCompact = function fromCompact(block) { }; TXRequest.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); var i, count, index, offset; this.hash = p.readHash('hex'); @@ -474,7 +477,7 @@ TXRequest.fromRaw = function fromRaw(data) { }; TXRequest.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var i, index; p.writeHash(this.hash); @@ -523,7 +526,7 @@ TXResponse.fromOptions = function fromOptions(options) { }; TXResponse.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); var i, count; this.hash = p.readHash('hex'); @@ -531,7 +534,7 @@ TXResponse.prototype.fromRaw = function fromRaw(data) { count = p.readVarint(); for (i = 0; i < count; i++) - this.txs.push(bcoin.tx.fromRaw(p)); + this.txs.push(TX.fromRaw(p)); return this; }; @@ -568,7 +571,7 @@ TXResponse.prototype.toNormal = function toNormal(writer) { }; TXResponse.prototype.frame = function frame(witness, writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var i, tx; p.writeHash(this.hash); diff --git a/lib/net/framer.js b/lib/net/framer.js index a3d4edb1..424fa97b 100644 --- a/lib/net/framer.js +++ b/lib/net/framer.js @@ -7,10 +7,9 @@ 'use strict'; -var bcoin = require('../env'); -var utils = require('../utils/utils'); +var Network = require('../protocol/network'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; +var assert = require('assert'); /** * Protocol packet framer @@ -28,7 +27,7 @@ function Framer(options) { this.options = options; - this.network = bcoin.network.get(options.network); + this.network = Network.get(options.network); this.bip151 = options.bip151; } diff --git a/lib/net/index.js b/lib/net/index.js new file mode 100644 index 00000000..d0ebdbfd --- /dev/null +++ b/lib/net/index.js @@ -0,0 +1,15 @@ +'use strict'; + +var lazy = require('../utils/lazy')(require, exports); + +lazy('bip150', './bip150'); +lazy('bip151', './bip151'); +lazy('bip152', './bip152'); +lazy('Framer', './framer'); +lazy('packets', './packets'); +lazy('Parser', './parser'); +lazy('Peer', './peer'); +lazy('Pool', './pool'); +lazy('ProxySocket', './proxysocket'); +lazy('time', './timedata'); +lazy('tcp', 'net'); diff --git a/lib/net/packets.js b/lib/net/packets.js index 130b917b..2bbd3c33 100644 --- a/lib/net/packets.js +++ b/lib/net/packets.js @@ -7,13 +7,26 @@ 'use strict'; -var bcoin = require('../env'); +var bn = require('bn.js'); var constants = require('../protocol/constants'); var utils = require('../utils/utils'); +var assert = require('assert'); var crypto = require('../crypto/crypto'); -var bn = require('bn.js'); +var time = require('./timedata'); +var ec = require('../crypto/ec'); +var Bloom = require('../utils/bloom'); +var bip152 = require('./bip152'); var NetworkAddress = require('../primitives/netaddress'); -var assert = utils.assert; +var Coin = require('../primitives/coin'); +var Headers = require('../primitives/headers'); +var InvItem = require('../primitives/invitem'); +var MemBlock = require('../primitives/memblock'); +var MerkleBlock = require('../primitives/merkleblock'); +var Outpoint = require('../primitives/outpoint'); +var Output = require('../primitives/output'); +var TX = require('../primitives/tx'); +var BufferWriter = require('../utils/writer'); +var BufferReader = require('../utils/reader'); var DUMMY = new Buffer(0); /** @@ -106,7 +119,7 @@ function VersionPacket(options) { this.version = constants.VERSION; this.services = constants.LOCAL_SERVICES; - this.ts = bcoin.now(); + this.ts = time.now(); this.recv = new NetworkAddress(); this.from = new NetworkAddress(); this.nonce = new bn(0); @@ -176,7 +189,7 @@ VersionPacket.fromOptions = function fromOptions(options) { */ VersionPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.write32(this.version); p.writeU64(this.services); @@ -256,7 +269,7 @@ VersionPacket.prototype.hasCompact = function hasCompact() { */ VersionPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.version = p.read32(); this.services = p.readU53(); @@ -376,7 +389,7 @@ PingPacket.prototype.type = exports.types.PING; */ PingPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); if (this.nonce) p.writeU64(this.nonce); @@ -394,7 +407,7 @@ PingPacket.prototype.toRaw = function toRaw(writer) { */ PingPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); if (p.left() >= 8) this.nonce = p.readU64(); return this; @@ -441,7 +454,7 @@ PongPacket.prototype.type = exports.types.PONG; */ PongPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.writeU64(this.nonce); @@ -458,7 +471,7 @@ PongPacket.prototype.toRaw = function toRaw(writer) { */ PongPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.nonce = p.readU64(); return this; }; @@ -498,18 +511,18 @@ PongPacket.fromRaw = function fromRaw(data, enc) { */ function AlertPacket(options) { - var time; + var ts; if (!(this instanceof AlertPacket)) return new AlertPacket(options); Packet.call(this); - time = bcoin.now() + 7 * 86400; + ts = time.now() + 7 * 86400; this.version = 1; - this.relayUntil = time; - this.expiration = time; + this.relayUntil = ts; + this.expiration = ts; this.id = 1; this.cancel = 0; this.cancels = []; @@ -625,7 +638,7 @@ AlertPacket.prototype.toPayload = function toPayload() { */ AlertPacket.prototype.sign = function sign(key) { - this.signature = bcoin.ec.sign(this.hash(), key); + this.signature = ec.sign(this.hash(), key); }; /** @@ -635,7 +648,7 @@ AlertPacket.prototype.sign = function sign(key) { */ AlertPacket.prototype.verify = function verify(key) { - return bcoin.ec.verify(this.hash(), this.signature, key); + return ec.verify(this.hash(), this.signature, key); }; /** @@ -644,7 +657,7 @@ AlertPacket.prototype.verify = function verify(key) { */ AlertPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.writeVarBytes(this.toPayload()); p.writeVarBytes(this.signature); @@ -662,7 +675,7 @@ AlertPacket.prototype.toRaw = function toRaw(writer) { */ AlertPacket.prototype.framePayload = function framePayload(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var i; p.write32(this.version); @@ -700,13 +713,13 @@ AlertPacket.prototype.framePayload = function framePayload(writer) { */ AlertPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); var i, count; this._payload = p.readVarBytes(); this.signature = p.readVarBytes(); - p = bcoin.reader(this._payload); + p = BufferReader(this._payload); this.version = p.read32(); this.relayUntil = p.read53(); @@ -824,7 +837,7 @@ AddrPacket.prototype.type = exports.types.ADDR; */ AddrPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var i; p.writeVarint(this.items.length); @@ -845,7 +858,7 @@ AddrPacket.prototype.toRaw = function toRaw(writer) { */ AddrPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); var i, count; count = p.readVarint(); @@ -897,7 +910,7 @@ InvPacket.prototype.type = exports.types.INV; */ InvPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var i; p.writeVarint(this.items.length); @@ -918,13 +931,13 @@ InvPacket.prototype.toRaw = function toRaw(writer) { */ InvPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); var i, count; count = p.readVarint(); for (i = 0; i < count; i++) - this.items.push(bcoin.invitem.fromRaw(p)); + this.items.push(InvItem.fromRaw(p)); return this; }; @@ -1040,7 +1053,7 @@ GetBlocksPacket.prototype.type = exports.types.GETBLOCKS; */ GetBlocksPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var i; p.writeU32(this.version); @@ -1064,7 +1077,7 @@ GetBlocksPacket.prototype.toRaw = function toRaw(writer) { */ GetBlocksPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); var i, count; this.version = p.readU32(); @@ -1157,7 +1170,7 @@ HeadersPacket.prototype.type = exports.types.HEADERS; */ HeadersPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var i; p.writeVarint(this.items.length); @@ -1178,13 +1191,13 @@ HeadersPacket.prototype.toRaw = function toRaw(writer) { */ HeadersPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); var i, count; count = p.readVarint(); for (i = 0; i < count; i++) - this.items.push(bcoin.headers.fromRaw(p)); + this.items.push(Headers.fromRaw(p)); return this; }; @@ -1268,7 +1281,7 @@ function BlockPacket(block, witness) { Packet.call(this); - this.block = block || new bcoin.memblock(); + this.block = block || new MemBlock(); this.witness = witness || false; } @@ -1328,7 +1341,7 @@ function TXPacket(tx, witness) { Packet.call(this); - this.tx = tx || new bcoin.tx(); + this.tx = tx || new TX(); this.witness = witness || false; } @@ -1450,7 +1463,7 @@ RejectPacket.fromOptions = function fromOptions(options) { */ RejectPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); assert(this.message.length <= 12); assert(this.reason.length <= 111); @@ -1475,7 +1488,7 @@ RejectPacket.prototype.toRaw = function toRaw(writer) { */ RejectPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.message = p.readVarString('ascii', 12); this.code = p.readU8(); @@ -1525,7 +1538,7 @@ RejectPacket.prototype.fromReason = function fromReason(code, reason, obj) { this.reason = reason; if (obj) { - this.message = (obj instanceof bcoin.tx) ? 'tx' : 'block'; + this.message = (obj instanceof TX) ? 'tx' : 'block'; this.data = obj.hash('hex'); } @@ -1639,7 +1652,7 @@ function FilterLoadPacket(filter, n, tweak, update) { Packet.call(this); - if (filter instanceof bcoin.bloom) { + if (filter instanceof Bloom) { this.fromFilter(filter); } else { this.filter = filter || DUMMY; @@ -1660,7 +1673,7 @@ FilterLoadPacket.prototype.type = exports.types.FILTERLOAD; */ FilterLoadPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.writeVarBytes(this.filter); p.writeU32(this.n); @@ -1679,7 +1692,7 @@ FilterLoadPacket.prototype.toRaw = function toRaw(writer) { */ FilterLoadPacket.prototype.toFilter = function toFilter() { - return new bcoin.bloom(this.filter, this.n, this.tweak, this.update); + return new Bloom(this.filter, this.n, this.tweak, this.update); }; /** @@ -1689,7 +1702,7 @@ FilterLoadPacket.prototype.toFilter = function toFilter() { */ FilterLoadPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.filter = p.readVarBytes(); this.n = p.readU32(); @@ -1782,7 +1795,7 @@ FilterAddPacket.prototype.type = exports.types.FILTERADD; */ FilterAddPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.writeVarBytes(this.data); @@ -1799,7 +1812,7 @@ FilterAddPacket.prototype.toRaw = function toRaw(writer) { */ FilterAddPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.data = p.readVarBytes(); return this; }; @@ -1881,7 +1894,7 @@ function MerkleBlockPacket(block) { Packet.call(this); - this.block = block || new bcoin.merkleblock(); + this.block = block || new MerkleBlock(); } utils.inherits(MerkleBlockPacket, Packet); @@ -1953,7 +1966,7 @@ GetUTXOsPacket.prototype.type = exports.types.GETUTXOS; */ GetUTXOsPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var i; p.writeU8(this.mempool ? 1 : 0); @@ -1975,7 +1988,7 @@ GetUTXOsPacket.prototype.toRaw = function toRaw(writer) { */ GetUTXOsPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); var i, count; this.mempool = p.readU8() === 1; @@ -1983,7 +1996,7 @@ GetUTXOsPacket.prototype.fromRaw = function fromRaw(data) { count = p.readVarint(); for (i = 0; i < count; i++) - this.prevout.push(bcoin.outpoint.fromRaw(p)); + this.prevout.push(Outpoint.fromRaw(p)); return this; }; @@ -2079,7 +2092,7 @@ UTXOsPacket.fromOptions = function fromOptions(options) { */ UTXOsPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var map = new Buffer((this.hits.length + 7) / 8 | 0); var i, bit, oct, coin, height; @@ -2120,7 +2133,7 @@ UTXOsPacket.prototype.toRaw = function toRaw(writer) { */ UTXOsPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); var i, bit, oct, coin, output; var version, height, map, count; @@ -2139,12 +2152,12 @@ UTXOsPacket.prototype.fromRaw = function fromRaw(data) { for (i = 0; i < count; i++) { version = p.readU32(); height = p.readU32(); - coin = new bcoin.coin(); + coin = new Coin(); if (height === 0x7fffffff) height = -1; - output = bcoin.output.fromRaw(p); + output = Output.fromRaw(p); coin.version = version; coin.height = height; @@ -2248,7 +2261,7 @@ FeeFilterPacket.prototype.type = exports.types.FEEFILTER; */ FeeFilterPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.write64(this.rate); @@ -2265,7 +2278,7 @@ FeeFilterPacket.prototype.toRaw = function toRaw(writer) { */ FeeFilterPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.rate = p.read64N(); return this; }; @@ -2314,7 +2327,7 @@ SendCmpctPacket.prototype.type = exports.types.SENDCMPCT; */ SendCmpctPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.writeU8(this.mode); p.writeU64(this.version); @@ -2332,7 +2345,7 @@ SendCmpctPacket.prototype.toRaw = function toRaw(writer) { */ SendCmpctPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.mode = p.readU8(); this.version = p.readU53(); return this; @@ -2367,7 +2380,7 @@ function CmpctBlockPacket(block, witness) { Packet.call(this); - this.block = block || new bcoin.bip152.CompactBlock(); + this.block = block || new bip152.CompactBlock(); this.witness = witness || false; } @@ -2425,7 +2438,7 @@ function GetBlockTxnPacket(request) { Packet.call(this); - this.request = request || new bcoin.bip152.TXRequest(); + this.request = request || new bip152.TXRequest(); } utils.inherits(GetBlockTxnPacket, Packet); @@ -2482,7 +2495,7 @@ function BlockTxnPacket(response, witness) { Packet.call(this); - this.response = response || new bcoin.bip152.TXResponse(); + this.response = response || new bip152.TXResponse(); this.witness = witness || false; } @@ -2557,7 +2570,7 @@ EncinitPacket.prototype.type = exports.types.ENCINIT; */ EncinitPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.writeBytes(this.publicKey); p.writeU8(this.cipher); @@ -2575,7 +2588,7 @@ EncinitPacket.prototype.toRaw = function toRaw(writer) { */ EncinitPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.publicKey = p.readBytes(33); this.cipher = p.readU8(); return this; @@ -2622,7 +2635,7 @@ EncackPacket.prototype.type = exports.types.ENCACK; */ EncackPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.writeBytes(this.publicKey); @@ -2639,7 +2652,7 @@ EncackPacket.prototype.toRaw = function toRaw(writer) { */ EncackPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.publicKey = p.readBytes(33); return this; }; @@ -2685,7 +2698,7 @@ AuthChallengePacket.prototype.type = exports.types.AUTHCHALLENGE; */ AuthChallengePacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.writeBytes(this.hash); @@ -2702,7 +2715,7 @@ AuthChallengePacket.prototype.toRaw = function toRaw(writer) { */ AuthChallengePacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.hash = p.readHash(); return this; }; @@ -2748,7 +2761,7 @@ AuthReplyPacket.prototype.type = exports.types.AUTHREPLY; */ AuthReplyPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.writeBytes(this.signature); @@ -2765,7 +2778,7 @@ AuthReplyPacket.prototype.toRaw = function toRaw(writer) { */ AuthReplyPacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.signature = p.readBytes(64); return this; }; @@ -2811,7 +2824,7 @@ AuthProposePacket.prototype.type = exports.types.AUTHPROPOSE; */ AuthProposePacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.writeBytes(this.hash); @@ -2828,7 +2841,7 @@ AuthProposePacket.prototype.toRaw = function toRaw(writer) { */ AuthProposePacket.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.hash = p.readHash(); return this; }; @@ -2876,7 +2889,7 @@ UnknownPacket.prototype.type = exports.types.UNKNOWN; */ UnknownPacket.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.writeBytes(this.data); diff --git a/lib/net/parser.js b/lib/net/parser.js index 2a4005af..455e5b8d 100644 --- a/lib/net/parser.js +++ b/lib/net/parser.js @@ -7,11 +7,11 @@ 'use strict'; -var bcoin = require('../env'); +var Network = require('../protocol/network'); var EventEmitter = require('events').EventEmitter; var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; +var assert = require('assert'); var constants = require('../protocol/constants'); var packets = require('./packets'); @@ -33,7 +33,7 @@ function Parser(options) { EventEmitter.call(this); - this.network = bcoin.network.get(options.network); + this.network = Network.get(options.network); this.bip151 = options.bip151; this.pending = []; diff --git a/lib/net/peer.js b/lib/net/peer.js index 62f2958e..fc3c6fe6 100644 --- a/lib/net/peer.js +++ b/lib/net/peer.js @@ -7,20 +7,26 @@ 'use strict'; -var bcoin = require('../env'); var EventEmitter = require('events').EventEmitter; var utils = require('../utils/utils'); var spawn = require('../utils/spawn'); var co = spawn.co; -var wrap = spawn.wrap; var Parser = require('./parser'); var Framer = require('./framer'); var packets = require('./packets'); var packetTypes = packets.types; var NetworkAddress = require('../primitives/netaddress'); -var assert = utils.assert; -var constants = bcoin.constants; -var InvItem = bcoin.invitem; +var assert = require('assert'); +var constants = require('../protocol/constants'); +var InvItem = require('../primitives/invitem'); +var Locker = require('../utils/locker'); +var Bloom = require('../utils/bloom'); +var BIP151 = require('./bip151'); +var BIP150 = require('./bip150'); +var BIP152 = require('./bip152'); +var Block = require('../primitives/block'); +var TX = require('../primitives/tx'); +var time = require('./timedata'); /** * Represents a remote peer. @@ -82,7 +88,7 @@ function Peer(pool, addr, socket) { this.chain = this.pool.chain; this.mempool = this.pool.mempool; this.network = this.chain.network; - this.locker = new bcoin.locker(); + this.locker = new Locker(); this.version = null; this.destroyed = false; this.ack = false; @@ -94,8 +100,8 @@ function Peer(pool, addr, socket) { this.spvFilter = null; this.relay = true; this.feeRate = -1; - this.addrFilter = new bcoin.bloom.rolling(5000, 0.001); - this.invFilter = new bcoin.bloom.rolling(50000, 0.000001); + this.addrFilter = new Bloom.rolling(5000, 0.001); + this.invFilter = new Bloom.rolling(50000, 0.000001); this.lastBlock = null; this.waiting = 0; this.syncSent = false; @@ -145,9 +151,9 @@ function Peer(pool, addr, socket) { } if (this.options.bip151) { - this.bip151 = new bcoin.bip151(); + this.bip151 = new BIP151(); if (this.options.bip150) { - this.bip150 = new bcoin.bip150( + this.bip150 = new BIP150( this.bip151, this.hostname, this.outbound, @@ -509,7 +515,7 @@ Peer.prototype.announce = co(function* announce(items) { // Send them the block immediately if // they're using compact block mode 1. if (this.compactMode && this.compactMode.mode === 1) { - if (item instanceof bcoin.block) { + if (item instanceof Block) { if (!this.invFilter.added(item.hash())) continue; yield this._sendCompactBlock(item, false); @@ -625,7 +631,7 @@ Peer.prototype.sendVersion = function sendVersion() { var packet = new packets.VersionPacket({ version: constants.VERSION, services: this.pool.services, - ts: bcoin.now(), + ts: time.now(), recv: new NetworkAddress(), from: this.pool.address, nonce: this.pool.localNonce, @@ -672,10 +678,10 @@ Peer.prototype.isWatched = function isWatched(item) { if (!item) return true; - if (item instanceof bcoin.tx) + if (item instanceof TX) return item.isWatched(this.spvFilter); - if (item.msg instanceof bcoin.tx) + if (item.msg instanceof TX) return item.msg.isWatched(this.spvFilter); return true; @@ -1578,7 +1584,7 @@ Peer.prototype._sendCompactBlock = function _sendCompactBlock(block, witness) { // if we get a siphash collision. for (;;) { try { - block = bcoin.bip152.CompactBlock.fromBlock(block); + block = BIP152.CompactBlock.fromBlock(block); } catch (e) { continue; } @@ -2002,14 +2008,14 @@ Peer.prototype._handleEncinit = co(function* _handleEncinit(packet) { * @param {EncackPacket} */ -Peer.prototype._handleEncack = co(function* _handleEncack(packet) { +Peer.prototype._handleEncack = function _handleEncack(packet) { if (!this.bip151) return; this.bip151.encack(packet.publicKey); this.fire('encack', packet); -}); +}; /** * Handle `authchallenge` packet. @@ -2202,7 +2208,7 @@ Peer.prototype._handleGetBlockTxn = co(function* _handleGetBlockTxn(packet) { return; } - res = bcoin.bip152.TXResponse.fromBlock(block, req); + res = BIP152.TXResponse.fromBlock(block, req); yield this.send(new packets.BlockTxnPacket(res, false)); diff --git a/lib/net/pool.js b/lib/net/pool.js index c566dfa4..e5f6ba26 100644 --- a/lib/net/pool.js +++ b/lib/net/pool.js @@ -7,19 +7,27 @@ 'use strict'; -var bcoin = require('../env'); var AsyncObject = require('../utils/async'); var EventEmitter = require('events').EventEmitter; var utils = require('../utils/utils'); var IP = require('../utils/ip'); var spawn = require('../utils/spawn'); var co = spawn.co; -var assert = utils.assert; -var constants = bcoin.constants; -var VerifyError = bcoin.errors.VerifyError; +var assert = require('assert'); +var constants = require('../protocol/constants'); +var VerifyError = require('../utils/errors').VerifyError; var NetworkAddress = require('../primitives/netaddress'); -var InvItem = bcoin.invitem; var VerifyResult = utils.VerifyResult; +var Address = require('../primitives/address'); +var BIP150 = require('./bip150'); +var Bloom = require('../utils/bloom'); +var ec = require('../crypto/ec'); +var InvItem = require('../primitives/invitem'); +var Locker = require('../utils/locker'); +var Network = require('../protocol/network'); +var time = require('./timedata'); +var Peer = require('./peer'); +var TX = require('../primitives/tx'); /** * A pool of peers for handling all network activity. @@ -103,7 +111,7 @@ function Pool(options) { this.connected = false; this.uid = 0; this.createServer = null; - this.locker = new bcoin.locker(); + this.locker = new Locker(); this.proxyServer = null; this.auth = null; this.identityKey = null; @@ -183,7 +191,7 @@ Pool.prototype._initOptions = function _initOptions() { if (this.options.bip150) { this.options.bip151 = true; - this.auth = new bcoin.bip150.AuthDB(); + this.auth = new BIP150.AuthDB(); if (this.options.authPeers) this.auth.setAuthorized(this.options.authPeers); @@ -191,10 +199,10 @@ Pool.prototype._initOptions = function _initOptions() { if (this.options.knownPeers) this.auth.setKnown(this.options.knownPeers); - this.identityKey = this.options.identityKey || bcoin.ec.generatePrivateKey(); + this.identityKey = this.options.identityKey || ec.generatePrivateKey(); assert(Buffer.isBuffer(this.identityKey), 'Identity key must be a buffer.'); - assert(bcoin.ec.privateKeyVerify(this.identityKey), + assert(ec.privateKeyVerify(this.identityKey), 'Invalid identity key.'); } @@ -223,10 +231,10 @@ Pool.prototype._initOptions = function _initOptions() { } if (this.options.spv) - this.spvFilter = bcoin.bloom.fromRate(10000, 0.001, constants.bloom.NONE); + this.spvFilter = Bloom.fromRate(10000, 0.001, constants.bloom.NONE); if (!this.options.mempool) - this.txFilter = new bcoin.bloom.rolling(50000, 0.000001); + this.txFilter = new Bloom.rolling(50000, 0.000001); if (this.options.requestTimeout != null) this.requestTimeout = this.options.requestTimeout; @@ -304,9 +312,9 @@ Pool.prototype._open = co(function* _open() { this.logger.info('Pool loaded (maxpeers=%d).', this.maxPeers); if (this.identityKey) { - key = bcoin.ec.publicKeyCreate(this.identityKey, true); + key = ec.publicKeyCreate(this.identityKey, true); this.logger.info('Identity public key: %s.', key.toString('hex')); - this.logger.info('Identity address: %s.', bcoin.bip150.address(key)); + this.logger.info('Identity address: %s.', BIP150.address(key)); } if (!this.options.listen) @@ -1021,7 +1029,7 @@ Pool.prototype.sendAlert = function sendAlert(alert) { Pool.prototype.createPeer = function createPeer(addr, socket) { var self = this; - var peer = new bcoin.peer(this, addr, socket); + var peer = new Peer(this, addr, socket); peer.once('open', function() { if (!peer.outbound) @@ -1215,7 +1223,7 @@ Pool.prototype.createPeer = function createPeer(addr, socket) { version.services.toString(2), version.agent); - bcoin.time.add(peer.hostname, version.ts); + time.add(peer.hostname, version.ts); self.emit('version', version, peer); }); @@ -1253,7 +1261,7 @@ Pool.prototype.createPeer = function createPeer(addr, socket) { */ Pool.prototype._handleAlert = function _handleAlert(alert, peer) { - var now = bcoin.now(); + var now = time.now(); if (!alert.verify(this.network.alertKey)) { this.logger.warning('Peer sent a phony alert packet (%s).', peer.hostname); @@ -1287,7 +1295,7 @@ Pool.prototype._handleAlert = function _handleAlert(alert, peer) { } // Keep alert disabled on main. - if (this.network === bcoin.network.main) { + if (this.network === Network.main) { // https://github.com/bitcoin/bitcoin/pull/7692#issuecomment-197967429 this.logger.warning('The Japanese government sent an alert packet.'); this.logger.warning('Here is their IP: %s.', peer.hostname); @@ -1524,7 +1532,7 @@ Pool.prototype.updateWatch = function updateWatch() { */ Pool.prototype.watchAddress = function watchAddress(address) { - this.watch(bcoin.address.getHash(address)); + this.watch(Address.getHash(address)); }; /** @@ -2437,7 +2445,7 @@ function BroadcastItem(pool, item, callback) { this.id = this.pool.uid++; this.msg = null; - if (item instanceof bcoin.tx) + if (item instanceof TX) assert(!item.mutable, 'Cannot broadcast mutable TX.'); if (item.toInv) { diff --git a/lib/net/proxysocket.js b/lib/net/proxysocket.js index 15ead76a..3e64ea43 100644 --- a/lib/net/proxysocket.js +++ b/lib/net/proxysocket.js @@ -1,10 +1,9 @@ 'use strict'; -var bcoin = require('../env'); -var utils = bcoin.utils; +var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); var BufferWriter = require('../utils/writer'); -var assert = utils.assert; +var assert = require('assert'); var EventEmitter = require('events').EventEmitter; var IOClient = require('socket.io-client'); diff --git a/lib/node/config.js b/lib/node/config.js index 991a6540..07885290 100644 --- a/lib/node/config.js +++ b/lib/node/config.js @@ -8,7 +8,7 @@ var Network = require('../protocol/network'); var utils = require('../utils/utils'); -var assert = utils.assert; +var assert = require('assert'); var fs; if (!utils.isBrowser) diff --git a/lib/node/fullnode.js b/lib/node/fullnode.js index 83a7bd8c..d03e0592 100644 --- a/lib/node/fullnode.js +++ b/lib/node/fullnode.js @@ -7,12 +7,18 @@ 'use strict'; -var bcoin = require('../env'); -var constants = bcoin.constants; +var constants = require('../protocol/constants'); var utils = require('../utils/utils'); var spawn = require('../utils/spawn'); var co = spawn.co; -var Node = bcoin.node; +var Node = require('./node'); +var Chain = require('../chain/chain'); +var Fees = require('../mempool/fees'); +var Mempool = require('../mempool/mempool'); +var Pool = require('../net/pool'); +var Miner = require('../miner/miner'); +var WalletDB = require('../wallet/walletdb'); +var http = require('../http'); /** * Create a fullnode complete with a chain, @@ -55,7 +61,7 @@ function Fullnode(options) { Node.call(this, options); // Instantiate blockchain. - this.chain = new bcoin.chain({ + this.chain = new Chain({ network: this.network, logger: this.logger, db: this.options.db, @@ -72,13 +78,13 @@ function Fullnode(options) { }); // Fee estimation. - this.fees = new bcoin.fees( + this.fees = new Fees( constants.tx.MIN_RELAY, this.network, this.logger); // Mempool needs access to the chain. - this.mempool = new bcoin.mempool({ + this.mempool = new Mempool({ network: this.network, logger: this.logger, chain: this.chain, @@ -92,7 +98,7 @@ function Fullnode(options) { }); // Pool needs access to the chain and mempool. - this.pool = new bcoin.pool({ + this.pool = new Pool({ network: this.network, logger: this.logger, chain: this.chain, @@ -117,7 +123,7 @@ function Fullnode(options) { }); // Miner needs access to the chain and mempool. - this.miner = new bcoin.miner({ + this.miner = new Miner({ network: this.network, logger: this.logger, chain: this.chain, @@ -128,7 +134,7 @@ function Fullnode(options) { }); // Wallet database needs access to fees. - this.walletdb = new bcoin.walletdb({ + this.walletdb = new WalletDB({ network: this.network, logger: this.logger, fees: this.fees, @@ -142,7 +148,7 @@ function Fullnode(options) { // HTTP needs access to the node. if (!utils.isBrowser) { - this.http = new bcoin.http.server({ + this.http = new http.Server({ network: this.network, logger: this.logger, node: this, diff --git a/lib/node/index.js b/lib/node/index.js new file mode 100644 index 00000000..fc6b493c --- /dev/null +++ b/lib/node/index.js @@ -0,0 +1,9 @@ +'use strict'; + +var lazy = require('../utils/lazy')(require, exports); + +lazy('config', './config'); +lazy('Fullnode', './fullnode'); +lazy('Logger', './logger'); +lazy('Node', './node'); +lazy('SPVNode', './spvnode'); diff --git a/lib/node/node.js b/lib/node/node.js index 8c2a63fb..6ae7de82 100644 --- a/lib/node/node.js +++ b/lib/node/node.js @@ -7,12 +7,15 @@ 'use strict'; -var bcoin = require('../env'); var AsyncObject = require('../utils/async'); var utils = require('../utils/utils'); var spawn = require('../utils/spawn'); var co = spawn.co; -var assert = utils.assert; +var assert = require('assert'); +var Network = require('../protocol/network'); +var Logger = require('./logger'); +var time = require('../net/timedata'); +var workers = require('../workers/workers'); /** * Base class from which every other @@ -35,7 +38,7 @@ function Node(options) { this.parseOptions(options); this.options = options; - this.network = bcoin.network.get(options.network); + this.network = Network.get(options.network); this.prefix = options.prefix; this.logger = options.logger; @@ -64,7 +67,7 @@ Node.prototype.__init = function __init() { var self = this; if (!this.logger) { - this.logger = new bcoin.logger({ + this.logger = new Logger({ level: this.options.logLevel || 'none', console: this.options.logConsole, file: this.options.logFile @@ -89,28 +92,28 @@ Node.prototype._onOpen = function _onOpen() { this.logger.open(); - this._bind(bcoin.time, 'offset', function(offset) { + this._bind(time, 'offset', function(offset) { self.logger.info('Time offset: %d (%d minutes).', offset, offset / 60 | 0); }); - this._bind(bcoin.time, 'sample', function(sample, total) { + this._bind(time, 'sample', function(sample, total) { self.logger.debug('Added time data: samples=%d, offset=%d (%d minutes).', total, sample, sample / 60 | 0); }); - this._bind(bcoin.time, 'mismatch', function() { + this._bind(time, 'mismatch', function() { self.logger.warning('Please make sure your system clock is correct!'); }); - this._bind(bcoin.workerPool, 'spawn', function(child) { + this._bind(workers.pool, 'spawn', function(child) { self.logger.info('Spawning worker process: %d.', child.id); }); - this._bind(bcoin.workerPool, 'exit', function(code, child) { + this._bind(workers.pool, 'exit', function(code, child) { self.logger.warning('Worker %d exited: %s.', child.id, code); }); - this._bind(bcoin.workerPool, 'error', function(err, child) { + this._bind(workers.pool, 'error', function(err, child) { if (child) { self.logger.error('Worker %d error: %s', child.id, err.message); return; @@ -181,7 +184,7 @@ Node.prototype._error = function _error(err) { */ Node.prototype.parseOptions = function parseOptions(options) { - options.network = bcoin.network.get(options.network); + options.network = Network.get(options.network); if (!options.prefix) options.prefix = utils.HOME + '/.bcoin'; diff --git a/lib/node/spvnode.js b/lib/node/spvnode.js index cc6b04e9..e56fb1cd 100644 --- a/lib/node/spvnode.js +++ b/lib/node/spvnode.js @@ -7,11 +7,14 @@ 'use strict'; -var bcoin = require('../env'); var utils = require('../utils/utils'); var spawn = require('../utils/spawn'); var co = spawn.co; -var Node = bcoin.node; +var Node = require('./node'); +var Chain = require('../chain/chain'); +var Pool = require('../net/pool'); +var WalletDB = require('../wallet/walletdb'); +var http = require('../http'); /** * Create an spv node which only maintains @@ -42,7 +45,7 @@ function SPVNode(options) { Node.call(this, options); - this.chain = new bcoin.chain({ + this.chain = new Chain({ network: this.network, logger: this.logger, db: this.options.db, @@ -53,7 +56,7 @@ function SPVNode(options) { spv: true }); - this.pool = new bcoin.pool({ + this.pool = new Pool({ network: this.network, logger: this.logger, chain: this.chain, @@ -71,7 +74,7 @@ function SPVNode(options) { spv: true }); - this.walletdb = new bcoin.walletdb({ + this.walletdb = new WalletDB({ network: this.network, logger: this.logger, db: this.options.db, @@ -82,7 +85,7 @@ function SPVNode(options) { }); if (!utils.isBrowser) { - this.http = new bcoin.http.server({ + this.http = new http.Server({ network: this.network, logger: this.logger, node: this, diff --git a/lib/primitives/abstractblock.js b/lib/primitives/abstractblock.js index 38ac4a3f..b0ad72ec 100644 --- a/lib/primitives/abstractblock.js +++ b/lib/primitives/abstractblock.js @@ -7,12 +7,17 @@ 'use strict'; -var bcoin = require('../env'); -var constants = bcoin.constants; -var utils = bcoin.utils; +module.exports = AbstractBlock; + +var constants = require('../protocol/constants'); +var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; +var assert = require('assert'); var VerifyResult = utils.VerifyResult; +var BufferWriter = require('../utils/writer'); +var time = require('../net/timedata'); +var InvItem = require('./invitem'); +var Headers = require('./headers'); /** * The class which all block-like objects inherit from. @@ -151,7 +156,7 @@ AbstractBlock.prototype.hash = function hash(enc) { */ AbstractBlock.prototype.abbr = function abbr(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.write32(this.version); p.writeHash(this.prevBlock); @@ -205,7 +210,7 @@ AbstractBlock.prototype.verifyHeaders = function verifyHeaders(ret) { } // Check timestamp against now + 2 hours - if (this.ts > bcoin.now() + 2 * 60 * 60) { + if (this.ts > time.now() + 2 * 60 * 60) { ret.reason = 'time-too-new'; ret.score = 0; return false; @@ -242,7 +247,7 @@ AbstractBlock.prototype.__defineGetter__('rhash', function() { */ AbstractBlock.prototype.toInv = function toInv() { - return new bcoin.invitem(constants.inv.BLOCK, this.hash('hex')); + return new InvItem(constants.inv.BLOCK, this.hash('hex')); }; /** @@ -251,7 +256,7 @@ AbstractBlock.prototype.toInv = function toInv() { */ AbstractBlock.prototype.toHeaders = function toHeaders() { - var headers = new bcoin.headers(this); + var headers = new Headers(this); headers._hash = this._hash; headers._valid = true; return headers; diff --git a/lib/primitives/address.js b/lib/primitives/address.js index 3a1ea995..82d62ff1 100644 --- a/lib/primitives/address.js +++ b/lib/primitives/address.js @@ -7,12 +7,14 @@ 'use strict'; +module.exports = Address; + var Network = require('../protocol/network'); var networks = require('../protocol/networks'); var constants = require('../protocol/constants'); var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; +var assert = require('assert'); var BufferWriter = require('../utils/writer'); var BufferReader = require('../utils/reader'); var Script = require('../script/script'); diff --git a/lib/primitives/block.js b/lib/primitives/block.js index 2b51622d..384cdcec 100644 --- a/lib/primitives/block.js +++ b/lib/primitives/block.js @@ -7,13 +7,19 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = Block; + var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; -var constants = bcoin.constants; -var AbstractBlock = bcoin.abstractblock; +var assert = require('assert'); +var constants = require('../protocol/constants'); +var AbstractBlock = require('./abstractblock'); var VerifyResult = utils.VerifyResult; +var BufferWriter = require('../utils/writer'); +var BufferReader = require('../utils/reader'); +var TX = require('./tx'); +var MerkleBlock = require('./merkleblock'); +var Network = require('../protocol/network'); /** * Represents a full block. @@ -162,7 +168,7 @@ Block.prototype.getSizes = function getSizes() { }; } - writer = new bcoin.writer(); + writer = new BufferWriter(); this.toRaw(writer); return { @@ -262,7 +268,7 @@ Block.prototype.hasTX = function hasTX(hash) { Block.prototype.indexOf = function indexOf(hash) { var i; - if (hash instanceof bcoin.tx) + if (hash instanceof TX) hash = hash.hash('hex'); for (i = 0; i < this.txs.length; i++) { @@ -534,7 +540,7 @@ Block.reward = function reward(height, network) { assert(height >= 0, 'Bad height for reward.'); - network = bcoin.network.get(network); + network = Network.get(network); halvings = height / network.halvingInterval | 0; // BIP 42 (well, our own version of it, @@ -647,7 +653,7 @@ Block.prototype.fromJSON = function fromJSON(json) { this.parseJSON(json); for (i = 0; i < json.txs.length; i++) - this.txs.push(bcoin.tx.fromJSON(json.txs[i])); + this.txs.push(TX.fromJSON(json.txs[i])); return this; }; @@ -669,7 +675,7 @@ Block.fromJSON = function fromJSON(json) { */ Block.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); var i, tx, witnessSize; p.start(); @@ -685,7 +691,7 @@ Block.prototype.fromRaw = function fromRaw(data) { witnessSize = 0; for (i = 0; i < this.totalTX; i++) { - tx = bcoin.tx.fromRaw(p); + tx = TX.fromRaw(p); witnessSize += tx._witnessSize; this.addTX(tx); } @@ -721,7 +727,7 @@ Block.fromRaw = function fromRaw(data, enc) { */ Block.prototype.toMerkle = function toMerkle(filter) { - return bcoin.merkleblock.fromBlock(this, filter); + return MerkleBlock.fromBlock(this, filter); }; /** @@ -733,7 +739,7 @@ Block.prototype.toMerkle = function toMerkle(filter) { */ Block.prototype.frame = function frame(witness, writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var witnessSize = 0; var i, tx; diff --git a/lib/primitives/coin.js b/lib/primitives/coin.js index 92bf2ffe..af40a9bd 100644 --- a/lib/primitives/coin.js +++ b/lib/primitives/coin.js @@ -7,11 +7,20 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = Coin; + var utils = require('../utils/utils'); -var constants = bcoin.constants; -var assert = utils.assert; -var Output = bcoin.output; +var constants = require('../protocol/constants'); +var Network = require('../protocol/network'); +var assert = require('assert'); +var Output = require('./output'); +var Script = require('../script/script'); +var Network = require('../protocol/network'); +var BufferWriter = require('../utils/writer'); +var BufferReader = require('../utils/reader'); +var compressor = require('../chain/compress'); +var compress = compressor.compress; +var decompress = compressor.decompress; /** * Represents an unspent output. @@ -36,7 +45,7 @@ function Coin(options) { this.version = 1; this.height = -1; this.value = 0; - this.script = new bcoin.script(); + this.script = new Script(); this.coinbase = true; this.hash = constants.NULL_HASH; this.index = 0; @@ -95,7 +104,7 @@ Coin.fromOptions = function fromOptions(options) { Coin.prototype.getConfirmations = function getConfirmations(height) { if (height == null) - height = bcoin.network.get().height; + height = Network.primary.height; if (this.height === -1) return 0; @@ -210,7 +219,7 @@ Coin.prototype.fromJSON = function fromJSON(json) { */ Coin.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var height = this.height; if (height === -1) @@ -235,7 +244,7 @@ Coin.prototype.toRaw = function toRaw(writer) { */ Coin.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.version = p.readU32(); this.height = p.readU32(); @@ -269,8 +278,7 @@ Coin.fromRaw = function fromRaw(data, enc) { */ Coin.prototype.toCompressed = function toCompressed(writer) { - var compress = bcoin.coins.compress; - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var height = this.height; var bits; @@ -303,8 +311,7 @@ Coin.prototype.toCompressed = function toCompressed(writer) { */ Coin.prototype.fromCompressed = function fromCompressed(data) { - var decompress = bcoin.coins.decompress; - var p = bcoin.reader(data); + var p = BufferReader(data); var bits; this.version = p.readVarint(); @@ -341,7 +348,7 @@ Coin.fromCompressed = function fromCompressed(data, enc) { */ Coin.prototype.toExtended = function toExtended(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); this.toRaw(p); p.writeHash(this.hash); @@ -360,7 +367,7 @@ Coin.prototype.toExtended = function toExtended(writer) { */ Coin.prototype.fromExtended = function fromExtended(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.fromRaw(p); this.hash = p.readHash('hex'); this.index = p.readU32(); diff --git a/lib/primitives/headers.js b/lib/primitives/headers.js index bffd2dc4..9a5e6e86 100644 --- a/lib/primitives/headers.js +++ b/lib/primitives/headers.js @@ -7,9 +7,12 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = Headers; + var utils = require('../utils/utils'); -var AbstractBlock = bcoin.abstractblock; +var AbstractBlock = require('./abstractblock'); +var BufferWriter = require('../utils/writer'); +var BufferReader = require('../utils/reader'); /** * Represents block headers obtained from the network via `headers`. @@ -46,7 +49,7 @@ Headers.prototype._verify = function _verify(ret) { */ Headers.prototype.getSize = function getSize() { - var writer = new bcoin.writer(); + var writer = new BufferWriter(); this.toRaw(writer); return writer.written; }; @@ -80,7 +83,7 @@ Headers.prototype.inspect = function inspect() { */ Headers.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.write32(this.version); p.writeHash(this.prevBlock); @@ -103,7 +106,7 @@ Headers.prototype.toRaw = function toRaw(writer) { */ Headers.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.version = p.readU32(); // Technically signed this.prevBlock = p.readHash('hex'); @@ -136,7 +139,7 @@ Headers.fromRaw = function fromRaw(data, enc) { */ Headers.prototype.fromAbbr = function fromAbbr(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.version = p.readU32(); // Technically signed this.prevBlock = p.readHash('hex'); diff --git a/lib/primitives/index.js b/lib/primitives/index.js new file mode 100644 index 00000000..bf0f5d1c --- /dev/null +++ b/lib/primitives/index.js @@ -0,0 +1,19 @@ +'use strict'; + +var lazy = require('../utils/lazy')(require, exports); + +lazy('AbstractBlock', './abstractblock'); +lazy('Address', './address'); +lazy('Block', './block'); +lazy('Coin', './coin'); +lazy('Headers', './headers'); +lazy('Input', './input'); +lazy('InvItem', './invitem'); +lazy('KeyRing', './keyring'); +lazy('MemBlock', './memblock'); +lazy('MerkleBlock', './merkleblock'); +lazy('MTX', './mtx'); +lazy('NetworkAddress', './netaddress'); +lazy('Outpoint', './outpoint'); +lazy('Output', './output'); +lazy('TX', './tx'); diff --git a/lib/primitives/input.js b/lib/primitives/input.js index a7ca2f52..1f8b3c9a 100644 --- a/lib/primitives/input.js +++ b/lib/primitives/input.js @@ -7,11 +7,17 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = Input; + var utils = require('../utils/utils'); -var assert = utils.assert; -var constants = bcoin.constants; +var assert = require('assert'); +var constants = require('../protocol/constants'); +var Script = require('../script/script'); +var Witness = require('../script/witness'); var Outpoint = require('./outpoint'); +var Coin = require('./coin'); +var BufferWriter = require('../utils/writer'); +var BufferReader = require('../utils/reader'); /** * Represents a transaction input. @@ -30,9 +36,9 @@ function Input(options) { return new Input(options); this.prevout = new Outpoint(); - this.script = new bcoin.script(); + this.script = new Script(); this.sequence = 0xffffffff; - this.witness = new bcoin.witness(); + this.witness = new Witness(); this.coin = null; this.mutable = false; this._address = null; @@ -65,7 +71,7 @@ Input.prototype.fromOptions = function fromOptions(options) { this.witness.fromOptions(options.witness); if (options.coin) - this.coin = bcoin.coin(options.coin); + this.coin = Coin(options.coin); return this; }; @@ -277,7 +283,7 @@ Input.prototype.fromJSON = function fromJSON(json) { assert(json, 'Input data is required.'); assert(utils.isNumber(json.sequence)); this.prevout.fromJSON(json.prevout); - this.coin = json.coin ? bcoin.coin.fromJSON(json.coin) : null; + this.coin = json.coin ? Coin.fromJSON(json.coin) : null; this.script.fromJSON(json.script); this.witness.fromJSON(json.witness); this.sequence = json.sequence; @@ -301,7 +307,7 @@ Input.fromJSON = function fromJSON(json) { */ Input.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); this.prevout.toRaw(p); p.writeVarBytes(this.script.toRaw()); @@ -319,7 +325,7 @@ Input.prototype.toRaw = function toRaw(writer) { */ Input.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.prevout.fromRaw(p); this.script.fromRaw(p.readVarBytes()); @@ -349,7 +355,7 @@ Input.fromRaw = function fromRaw(data, enc) { */ Input.prototype.toExtended = function toExtended(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); this.toRaw(p); this.witness.toRaw(p); @@ -367,7 +373,7 @@ Input.prototype.toExtended = function toExtended(writer) { */ Input.prototype.fromExtended = function fromExtended(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.fromRaw(p); this.witness.fromRaw(p); return this; @@ -420,7 +426,7 @@ Input.fromCoin = function fromCoin(coin) { */ Input.prototype.fromTX = function fromTX(tx, index) { - var coin = bcoin.coin.fromTX(tx, index); + var coin = Coin.fromTX(tx, index); return this.fromCoin(coin); }; diff --git a/lib/primitives/invitem.js b/lib/primitives/invitem.js index 4f8da655..204e86dc 100644 --- a/lib/primitives/invitem.js +++ b/lib/primitives/invitem.js @@ -7,8 +7,11 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = InvItem; + var constants = require('../protocol/constants'); +var BufferWriter = require('../utils/writer'); +var BufferReader = require('../utils/reader'); /** * Inv Item @@ -32,7 +35,7 @@ function InvItem(type, hash) { */ InvItem.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.writeU32(this.type); p.writeHash(this.hash); @@ -49,7 +52,7 @@ InvItem.prototype.toRaw = function toRaw(writer) { */ InvItem.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.type = p.readU32(); this.hash = p.readHash('hex'); return this; diff --git a/lib/primitives/keyring.js b/lib/primitives/keyring.js index 436f6afe..708607fe 100644 --- a/lib/primitives/keyring.js +++ b/lib/primitives/keyring.js @@ -7,16 +7,20 @@ 'use strict'; -var bcoin = require('../env'); -var constants = bcoin.constants; -var utils = bcoin.utils; +module.exports = KeyRing; + +var constants = require('../protocol/constants'); +var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; -var networks = bcoin.networks; +var assert = require('assert'); +var networks = require('../protocol/networks'); +var Network = require('../protocol/network'); var BufferReader = require('../utils/reader'); var BufferWriter = require('../utils/writer'); -var scriptTypes = constants.scriptTypes; +var Script = require('../script/script'); var Address = require('./address'); +var Input = require('./input'); +var Output = require('./output'); var ec = require('../crypto/ec'); /** @@ -35,7 +39,7 @@ function KeyRing(options, network) { if (!(this instanceof KeyRing)) return new KeyRing(options, network); - this.network = bcoin.network.get(); + this.network = Network.primary; this.witness = false; this.nested = false; this.publicKey = constants.ZERO_KEY; @@ -65,7 +69,9 @@ KeyRing.prototype.fromOptions = function fromOptions(options, network) { var key = toKey(options); var script = options.script; var compressed = options.compressed; - var network = options.network; + + if (!network) + network = options.network; if (Buffer.isBuffer(key)) return this.fromKey(key, network); @@ -121,7 +127,7 @@ KeyRing.prototype.fromPrivate = function fromPrivate(key, compressed, network) { compressed = null; } - this.network = bcoin.network.get(network); + this.network = Network.get(network); this.privateKey = key; this.publicKey = ec.publicKeyCreate(key, compressed !== false); @@ -150,7 +156,7 @@ KeyRing.fromPrivate = function fromPrivate(key, compressed, network) { KeyRing.prototype.fromPublic = function fromPublic(key, network) { assert(Buffer.isBuffer(key), 'Public key must be a buffer.'); assert(ec.publicKeyVerify(key), 'Not a valid public key.'); - this.network = bcoin.network.get(network); + this.network = Network.get(network); this.publicKey = key; return this; }; @@ -237,7 +243,7 @@ KeyRing.fromKey = function fromKey(key, compressed, network) { */ KeyRing.prototype.fromScript = function fromScript(key, script, compressed, network) { - assert(script instanceof bcoin.script, 'Non-script passed into KeyRing.'); + assert(script instanceof Script, 'Non-script passed into KeyRing.'); if (typeof compressed !== 'boolean') { network = compressed; @@ -387,10 +393,10 @@ KeyRing.prototype.getProgram = function getProgram() { if (!this._program) { if (!this.script) { hash = crypto.hash160(this.publicKey); - program = bcoin.script.fromProgram(0, hash); + program = Script.fromProgram(0, hash); } else { hash = this.script.sha256(); - program = bcoin.script.fromProgram(0, hash); + program = Script.fromProgram(0, hash); } this._program = program; } @@ -431,7 +437,7 @@ KeyRing.prototype.getNestedAddress = function getNestedAddress(enc) { if (!this._nestedAddress) { hash = this.getNestedHash(); - address = this.compile(hash, scriptTypes.SCRIPTHASH); + address = this.compile(hash, Script.types.SCRIPTHASH); this._nestedAddress = address; } @@ -504,10 +510,10 @@ KeyRing.prototype.getScriptAddress = function getScriptAddress(enc) { if (!this._scriptAddress) { if (this.witness) { hash = this.getScriptHash256(); - address = this.compile(hash, scriptTypes.WITNESSSCRIPTHASH, 0); + address = this.compile(hash, Script.types.WITNESSSCRIPTHASH, 0); } else { hash = this.getScriptHash160(); - address = this.compile(hash, scriptTypes.SCRIPTHASH); + address = this.compile(hash, Script.types.SCRIPTHASH); } this._scriptAddress = address; } @@ -545,9 +551,9 @@ KeyRing.prototype.getKeyAddress = function getKeyAddress(enc) { if (!this._keyAddress) { hash = this.getKeyHash(); if (this.witness) - address = this.compile(hash, scriptTypes.WITNESSPUBKEYHASH, 0); + address = this.compile(hash, Script.types.WITNESSPUBKEYHASH, 0); else - address = this.compile(hash, scriptTypes.PUBKEYHASH); + address = this.compile(hash, Script.types.PUBKEYHASH); this._keyAddress = address; } @@ -633,7 +639,7 @@ KeyRing.prototype.ownHash = function ownHash(hash) { KeyRing.prototype.ownInput = function ownInput(tx, index) { var input; - if (tx instanceof bcoin.input) { + if (tx instanceof Input) { input = tx; } else { input = tx.inputs[index]; @@ -653,7 +659,7 @@ KeyRing.prototype.ownInput = function ownInput(tx, index) { KeyRing.prototype.ownOutput = function ownOutput(tx, index) { var output; - if (tx instanceof bcoin.output) { + if (tx instanceof Output) { output = tx; } else { output = tx.outputs[index]; @@ -731,18 +737,18 @@ KeyRing.prototype.getVersion = function getVersion() { KeyRing.prototype.getType = function getType() { if (this.nested) - return scriptTypes.SCRIPTHASH; + return Script.types.SCRIPTHASH; if (this.witness) { if (this.script) - return scriptTypes.WITNESSSCRIPTHASH; - return scriptTypes.WITNESSPUBKEYHASH; + return Script.types.WITNESSSCRIPTHASH; + return Script.types.WITNESSPUBKEYHASH; } if (this.script) - return scriptTypes.SCRIPTHASH; + return Script.types.SCRIPTHASH; - return scriptTypes.PUBKEYHASH; + return Script.types.PUBKEYHASH; }; /* @@ -842,7 +848,7 @@ KeyRing.prototype.fromJSON = function fromJSON(json) { assert(typeof json.publicKey === 'string'); assert(!json.script || typeof json.script === 'string'); - this.nework = bcoin.network.get(json.network); + this.nework = Network.get(json.network); this.witness = json.witness; this.nested = json.nested; this.publicKey = new Buffer(json.publicKey, 'hex'); @@ -902,7 +908,7 @@ KeyRing.prototype.fromRaw = function fromRaw(data, network) { var p = new BufferReader(data); var compressed, key, script; - this.network = bcoin.network.get(network); + this.network = Network.get(network); this.witness = p.readU8() === 1; this.nested = p.readU8() === 1; @@ -920,7 +926,7 @@ KeyRing.prototype.fromRaw = function fromRaw(data, network) { script = p.readVarBytes(); if (script.length > 0) - this.script = bcoin.script.fromRaw(script); + this.script = Script.fromRaw(script); return this; }; diff --git a/lib/primitives/memblock.js b/lib/primitives/memblock.js index 6f303cc8..2a95b708 100644 --- a/lib/primitives/memblock.js +++ b/lib/primitives/memblock.js @@ -7,9 +7,13 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = MemBlock; + var utils = require('../utils/utils'); -var AbstractBlock = bcoin.abstractblock; +var AbstractBlock = require('./abstractblock'); +var Block = require('./block'); +var Script = require('../script/script'); +var BufferReader = require('../utils/reader'); /** * A block object which is essentially a "placeholder" @@ -113,7 +117,7 @@ MemBlock.prototype.getCoinbaseHeight = function getCoinbaseHeight() { */ MemBlock.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data, true); + var p = BufferReader(data, true); var height = -1; var inCount, input; @@ -137,7 +141,7 @@ MemBlock.prototype.fromRaw = function fromRaw(data) { if (inCount > 0) { p.seek(36); input = p.readVarBytes(); - height = bcoin.script.getCoinbaseHeight(input); + height = Script.getCoinbaseHeight(input); } } @@ -183,7 +187,7 @@ MemBlock.prototype.toNormal = function toNormal() { */ MemBlock.prototype.toBlock = function toBlock() { - var block = bcoin.block.fromRaw(this.raw); + var block = Block.fromRaw(this.raw); block._hash = this._hash; block._cbHeight = this.coinbaseHeight; this.raw = null; diff --git a/lib/primitives/merkleblock.js b/lib/primitives/merkleblock.js index a219dc1a..0f6a47fc 100644 --- a/lib/primitives/merkleblock.js +++ b/lib/primitives/merkleblock.js @@ -7,14 +7,18 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = MerkleBlock; + var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; -var constants = bcoin.constants; +var assert = require('assert'); +var constants = require('../protocol/constants'); var DUMMY = new Buffer([0]); -var AbstractBlock = bcoin.abstractblock; +var AbstractBlock = require('./abstractblock'); var VerifyResult = utils.VerifyResult; +var BufferWriter = require('../utils/writer'); +var BufferReader = require('../utils/reader'); +var TX = require('./tx'); /** * Represents a merkle (filtered) block. @@ -91,7 +95,7 @@ MerkleBlock.fromOptions = function fromOptions(data) { */ MerkleBlock.prototype.getSize = function getSize() { - var writer = new bcoin.writer(); + var writer = new BufferWriter(); this.toRaw(writer); return writer.written; }; @@ -131,7 +135,7 @@ MerkleBlock.prototype.hasTX = function hasTX(hash) { MerkleBlock.prototype.indexOf = function indexOf(hash) { var index; - if (hash instanceof bcoin.tx) + if (hash instanceof TX) hash = hash.hash('hex'); this.verifyPartial(); @@ -341,7 +345,7 @@ MerkleBlock.prototype.inspect = function inspect() { */ MerkleBlock.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var i; p.writeU32(this.version); @@ -372,7 +376,7 @@ MerkleBlock.prototype.toRaw = function toRaw(writer) { */ MerkleBlock.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); var i, hashCount; this.version = p.readU32(); diff --git a/lib/primitives/mtx.js b/lib/primitives/mtx.js index 9ef0eab7..caf87678 100644 --- a/lib/primitives/mtx.js +++ b/lib/primitives/mtx.js @@ -7,15 +7,24 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = MTX; + var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; -var constants = bcoin.constants; -var Script = bcoin.script; -var opcodes = constants.opcodes; -var FundingError = bcoin.errors.FundingError; -var TX = bcoin.tx; +var assert = require('assert'); +var constants = require('../protocol/constants'); +var Network = require('../protocol/network'); +var Script = require('../script/script'); +var opcodes = Script.opcodes; +var FundingError = require('../utils/errors').FundingError; +var TX = require('./tx'); +var Input = require('./input'); +var Output = require('./output'); +var Coin = require('./coin'); +var KeyRing = require('./keyring'); +var Address = require('./address'); +var ec = require('../crypto/ec'); +var workers = require('../workers/workers'); /** * A mutable transaction object. @@ -150,12 +159,12 @@ MTX.prototype.clone = function clone() { */ MTX.prototype.addInput = function addInput(options, index) { - var input = new bcoin.input(); + var input = new Input(); input.mutable = true; if (options instanceof TX) input.fromTX(options, index); - else if (options instanceof bcoin.coin) + else if (options instanceof Coin) input.fromCoin(options); else input.fromOptions(options); @@ -179,18 +188,16 @@ MTX.prototype.addInput = function addInput(options, index) { MTX.prototype.addOutput = function addOutput(options, value) { var output; - if ((options instanceof bcoin.wallet) - || (options instanceof bcoin.keyring)) { + if (options instanceof KeyRing) options = options.getAddress(); - } if (typeof options === 'string') - options = bcoin.address.fromBase58(options); + options = Address.fromBase58(options); - if (options instanceof bcoin.address) + if (options instanceof Address) options = Script.fromAddress(options); - output = new bcoin.output(); + output = new Output(); output.mutable = true; if (options instanceof Script) { @@ -395,7 +402,7 @@ MTX.prototype.scriptVector = function scriptVector(prev, vector, ring) { */ MTX.prototype.signInputAsync = function signInputAsync(index, key, type) { - return bcoin.workerPool.signInput(this, index, key, type); + return workers.pool.signInput(this, index, key, type); }; /** @@ -475,7 +482,7 @@ MTX.prototype.signInput = function signInput(index, key, type) { */ MTX.prototype.signVector = function signVector(prev, vector, sig, key) { - var pub = bcoin.ec.publicKeyCreate(key, true); + var pub = ec.publicKeyCreate(key, true); var i, m, n, keys, keyIndex, total; // P2PK @@ -903,7 +910,7 @@ MTX.prototype.sign = function sign(ring, type) { */ MTX.prototype.signAsync = function signAsync(ring, type) { - return bcoin.workerPool.sign(this, ring, type); + return workers.pool.sign(this, ring, type); }; /** @@ -1004,7 +1011,7 @@ MTX.prototype.maxSize = function maxSize(options) { if (redeem) { prev = redeem; sz = prev.getSize(); - size += bcoin.script.sizePush(sz); + size += Script.sizePush(sz); size += sz; } } @@ -1126,8 +1133,8 @@ MTX.prototype._guessRedeem = function guessRedeem(options, hash) { case 20: if (options.witness) { if (options.n > 1) - return bcoin.script.fromProgram(0, constants.ZERO_HASH); - return bcoin.script.fromProgram(0, constants.ZERO_HASH160); + return Script.fromProgram(0, constants.ZERO_HASH); + return Script.fromProgram(0, constants.ZERO_HASH160); } return options.script; case 32: @@ -1177,7 +1184,7 @@ MTX.prototype.subtractFee = function subtractFee(fee, index) { if (Array.isArray(index)) { addrs = []; for (i = 0; i < index.length; i++) { - hash = bcoin.address.getHash(index[i]); + hash = Address.getHash(index[i]); if (hash) addrs.push(hash); } @@ -1310,7 +1317,7 @@ MTX.prototype.sortMembers = function sortMembers() { MTX.prototype.avoidFeeSniping = function avoidFeeSniping(height) { if (height == null) - height = bcoin.network.get().height; + height = Network.primary.height; if (height === -1) height = 0; @@ -1535,9 +1542,9 @@ CoinSelector.prototype.fromOptions = function fromOptions(options) { if (options.changeAddress) { addr = options.changeAddress; if (typeof addr === 'string') { - this.changeAddress = bcoin.address.fromBase58(addr); + this.changeAddress = Address.fromBase58(addr); } else { - assert(addr instanceof bcoin.address); + assert(addr instanceof Address); this.changeAddress = addr; } } @@ -1560,7 +1567,7 @@ CoinSelector.prototype.fromOptions = function fromOptions(options) { } if (options.script) { - assert(options.script instanceof bcoin.script); + assert(options.script instanceof Script); this.script = options.script; } @@ -1662,9 +1669,9 @@ CoinSelector.prototype.getFee = function getFee(size) { var fee; if (this.round) - fee = bcoin.tx.getRoundFee(size, this.rate); + fee = TX.getRoundFee(size, this.rate); else - fee = bcoin.tx.getMinFee(size, this.rate); + fee = TX.getMinFee(size, this.rate); if (fee > constants.tx.MAX_FEE) fee = constants.tx.MAX_FEE; diff --git a/lib/primitives/netaddress.js b/lib/primitives/netaddress.js index 454d2e89..11a01d02 100644 --- a/lib/primitives/netaddress.js +++ b/lib/primitives/netaddress.js @@ -6,11 +6,16 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = NetworkAddress; + var constants = require('../protocol/constants'); +var Network = require('../protocol/network'); +var time = require('../net/timedata'); var utils = require('../utils/utils'); var IP = require('../utils/ip'); -var assert = utils.assert; +var assert = require('assert'); +var BufferWriter = require('../utils/writer'); +var BufferReader = require('../utils/reader'); /** * Represents a network address. @@ -183,14 +188,14 @@ NetworkAddress.prototype.inspect = function inspect() { NetworkAddress.prototype.fromHostname = function fromHostname(hostname, network) { var address = IP.parseHost(hostname); - network = bcoin.network.get(network); + network = Network.get(network); this.host = address.host; this.port = address.port || network.port; this.services = constants.services.NETWORK | constants.services.BLOOM | constants.services.WITNESS; - this.ts = bcoin.now(); + this.ts = time.now(); this.hostname = IP.hostname(this.host, this.port); @@ -224,7 +229,7 @@ NetworkAddress.prototype.fromSocket = function fromSocket(socket) { this.services = constants.services.NETWORK | constants.services.BLOOM | constants.services.WITNESS; - this.ts = bcoin.now(); + this.ts = time.now(); this.hostname = IP.hostname(this.host, this.port); @@ -250,8 +255,8 @@ NetworkAddress.fromSocket = function fromSocket(hostname) { */ NetworkAddress.prototype.fromRaw = function fromRaw(data, full) { - var p = bcoin.reader(data); - var now = bcoin.now(); + var p = BufferReader(data); + var now = time.now(); // only version >= 31402 this.ts = full ? p.readU32() : 0; @@ -285,7 +290,7 @@ NetworkAddress.fromRaw = function fromRaw(data, full) { */ NetworkAddress.prototype.toRaw = function toRaw(full, writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); if (full) p.writeU32(this.ts); diff --git a/lib/primitives/outpoint.js b/lib/primitives/outpoint.js index 34f1f50a..ce17d441 100644 --- a/lib/primitives/outpoint.js +++ b/lib/primitives/outpoint.js @@ -6,10 +6,13 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = Outpoint; + var utils = require('../utils/utils'); -var assert = utils.assert; -var constants = bcoin.constants; +var assert = require('assert'); +var constants = require('../protocol/constants'); +var BufferWriter = require('../utils/writer'); +var BufferReader = require('../utils/reader'); /** * Represents a COutPoint. @@ -69,7 +72,7 @@ Outpoint.prototype.isNull = function isNull() { */ Outpoint.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.writeHash(this.hash); p.writeU32(this.index); @@ -87,7 +90,7 @@ Outpoint.prototype.toRaw = function toRaw(writer) { */ Outpoint.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.hash = p.readHash('hex'); this.index = p.readU32(); return this; diff --git a/lib/primitives/output.js b/lib/primitives/output.js index 3d15e8ed..cbcf53de 100644 --- a/lib/primitives/output.js +++ b/lib/primitives/output.js @@ -7,10 +7,15 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = Output; + var utils = require('../utils/utils'); -var constants = bcoin.constants; -var assert = utils.assert; +var constants = require('../protocol/constants'); +var Script = require('../script/script'); +var BufferWriter = require('../utils/writer'); +var BufferReader = require('../utils/reader'); +var assert = require('assert'); +var TX = require('./tx'); /** * Represents a transaction output. @@ -26,7 +31,7 @@ function Output(options) { return new Output(options); this.value = 0; - this.script = new bcoin.script(); + this.script = new Script(); this.mutable = false; this._address = null; @@ -165,7 +170,7 @@ Output.prototype.getDustThreshold = function getDustThreshold(rate) { size += 32 + 4 + 1 + 107 + 4; } - return 3 * bcoin.tx.getMinFee(size, rate); + return 3 * TX.getMinFee(size, rate); }; /** @@ -174,7 +179,7 @@ Output.prototype.getDustThreshold = function getDustThreshold(rate) { */ Output.prototype.getSize = function getSize() { - return this.toRaw(bcoin.writer()).written; + return this.toRaw(BufferWriter()).written; }; /** @@ -217,7 +222,7 @@ Output.fromJSON = function fromJSON(json) { */ Output.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); p.write64(this.value); p.writeVarBytes(this.script.toRaw()); @@ -235,7 +240,7 @@ Output.prototype.toRaw = function toRaw(writer) { */ Output.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); this.value = p.read64N(); this.script.fromRaw(p.readVarBytes()); diff --git a/lib/primitives/tx.js b/lib/primitives/tx.js index 47517e7c..fbc31cca 100644 --- a/lib/primitives/tx.js +++ b/lib/primitives/tx.js @@ -7,15 +7,25 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = TX; + var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; -var constants = bcoin.constants; -var Script = bcoin.script; -var Stack = bcoin.stack; +var assert = require('assert'); +var constants = require('../protocol/constants'); +var Network = require('../protocol/network'); +var Script = require('../script/script'); +var Stack = require('../script/stack'); var BufferWriter = require('../utils/writer'); var VerifyResult = utils.VerifyResult; +var Input = require('./input'); +var Output = require('./output'); +var Outpoint = require('./outpoint'); +var Coin = require('./coin'); +var InvItem = require('./invitem'); +var workers = require('../workers/workers'); +var BufferWriter = require('../utils/writer'); +var BufferReader = require('../utils/reader'); /* * Constants @@ -117,13 +127,13 @@ TX.prototype.fromOptions = function fromOptions(options) { if (options.inputs) { assert(Array.isArray(options.inputs)); for (i = 0; i < options.inputs.length; i++) - this.inputs.push(new bcoin.input(options.inputs[i])); + this.inputs.push(new Input(options.inputs[i])); } if (options.outputs) { assert(Array.isArray(options.outputs)); for (i = 0; i < options.outputs.length; i++) - this.outputs.push(new bcoin.output(options.outputs[i])); + this.outputs.push(new Output(options.outputs[i])); } if (options.locktime != null) { @@ -720,7 +730,7 @@ TX.prototype.verifyAsync = function verifyAsync(flags) { if (this.isCoinbase()) return Promise.resolve(true); - return bcoin.workerPool.verify(this, flags); + return workers.pool.verify(this, flags); }; /** @@ -741,7 +751,7 @@ TX.prototype.verifyInputAsync = function verifyInputAsync(index, flags) { assert(input, 'Input does not exist.'); - return bcoin.workerPool.verifyInput(this, index, flags); + return workers.pool.verifyInput(this, index, flags); }; /** @@ -968,7 +978,7 @@ TX.prototype.fillCoins = function fillCoins(coins) { var result = true; var i, input, hash, index, map, coin; - if ((coins instanceof bcoin.coin) + if ((coins instanceof Coin) || (coins instanceof TX)) { coins = [coins]; } @@ -979,7 +989,7 @@ TX.prototype.fillCoins = function fillCoins(coins) { coin = coins[i]; if (coin instanceof TX) { map[coin.hash('hex')] = coin; - } else if (coin instanceof bcoin.coin) { + } else if (coin instanceof Coin) { assert(typeof coin.hash === 'string'); assert(typeof coin.index === 'number'); map[coin.hash + coin.index] = coin; @@ -1001,7 +1011,7 @@ TX.prototype.fillCoins = function fillCoins(coins) { coin = coins[hash]; if (coin) { - input.coin = bcoin.coin.fromTX(coin, index); + input.coin = Coin.fromTX(coin, index); continue; } @@ -1486,7 +1496,7 @@ TX.prototype.getWitnessStandard = function getWitnessStandard() { ret = BAD_NONSTD_P2WSH; } - redeem = new bcoin.script(redeem); + redeem = new Script(redeem); if (redeem.isPubkey()) { if (input.witness.length - 1 !== 1) @@ -1662,7 +1672,7 @@ TX.prototype.getPriority = function getPriority(height, size) { if (height == null) { height = this.height; if (height === -1) - height = bcoin.network.get().height; + height = Network.primary.height; } if (size == null) @@ -1791,7 +1801,7 @@ TX.prototype.getRate = function getRate(size) { TX.prototype.getConfirmations = function getConfirmations(height) { if (height == null) - height = bcoin.network.get().height; + height = Network.primary.height; if (this.height === -1) return 0; @@ -1851,11 +1861,11 @@ TX.prototype.isWatched = function isWatched(filter) { // Test the output script if (output.script.test(filter)) { if (filter.update === constants.filterFlags.ALL) { - outpoint = bcoin.outpoint.fromTX(this, i); + outpoint = Outpoint.fromTX(this, i); filter.add(outpoint.toRaw()); } else if (filter.update === constants.filterFlags.PUBKEY_ONLY) { if (output.script.isPubkey() || output.script.isMultisig()) { - outpoint = bcoin.outpoint.fromTX(this, i); + outpoint = Outpoint.fromTX(this, i); filter.add(outpoint.toRaw()); } } @@ -1917,7 +1927,7 @@ TX.prototype.__defineGetter__('wtxid', function() { */ TX.prototype.toInv = function toInv() { - return new bcoin.invitem(constants.inv.TX, this.hash('hex')); + return new InvItem(constants.inv.TX, this.hash('hex')); }; /** @@ -2074,12 +2084,12 @@ TX.prototype.fromJSON = function fromJSON(json) { for (i = 0; i < json.inputs.length; i++) { input = json.inputs[i]; - this.inputs.push(bcoin.input.fromJSON(input)); + this.inputs.push(Input.fromJSON(input)); } for (i = 0; i < json.outputs.length; i++) { output = json.outputs[i]; - this.outputs.push(bcoin.output.fromJSON(output)); + this.outputs.push(Output.fromJSON(output)); } this.locktime = json.locktime; @@ -2123,7 +2133,7 @@ TX.prototype.fromRaw = function fromRaw(data) { if (TX.isWitness(data)) return this.fromWitness(data); - p = bcoin.reader(data); + p = BufferReader(data); p.start(); this.version = p.readU32(); // Technically signed @@ -2131,12 +2141,12 @@ TX.prototype.fromRaw = function fromRaw(data) { inCount = p.readVarint(); for (i = 0; i < inCount; i++) - this.inputs.push(bcoin.input.fromRaw(p)); + this.inputs.push(Input.fromRaw(p)); outCount = p.readVarint(); for (i = 0; i < outCount; i++) - this.outputs.push(bcoin.output.fromRaw(p)); + this.outputs.push(Output.fromRaw(p)); this.locktime = p.readU32(); @@ -2159,7 +2169,7 @@ TX.prototype.fromRaw = function fromRaw(data) { */ TX.prototype.fromWitness = function fromWitness(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); var i, marker, inCount, outCount, input, hasWitness, witnessSize; p.start(); @@ -2178,12 +2188,12 @@ TX.prototype.fromWitness = function fromWitness(data) { inCount = p.readVarint(); for (i = 0; i < inCount; i++) - this.inputs.push(bcoin.input.fromRaw(p)); + this.inputs.push(Input.fromRaw(p)); outCount = p.readVarint(); for (i = 0; i < outCount; i++) - this.outputs.push(bcoin.output.fromRaw(p)); + this.outputs.push(Output.fromRaw(p)); p.start(); @@ -2241,7 +2251,7 @@ TX.isWitness = function isWitness(data) { */ TX.prototype.frameNormal = function frameNormal(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var i; if (this.inputs.length === 0 && this.outputs.length === 1) @@ -2278,7 +2288,7 @@ TX.prototype.frameNormal = function frameNormal(writer) { */ TX.prototype.frameWitness = function frameWitness(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var witnessSize = 0; var i, start; @@ -2331,7 +2341,7 @@ TX.prototype.frameWitness = function frameWitness(writer) { TX.prototype.toExtended = function toExtended(saveCoins, writer) { var height = this.height; var index = this.index; - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var i, input; if (height === -1) @@ -2377,7 +2387,7 @@ TX.prototype.toExtended = function toExtended(saveCoins, writer) { */ TX.prototype.fromExtended = function fromExtended(data, saveCoins) { - var p = bcoin.reader(data); + var p = BufferReader(data); var i, coinCount, coin; this.fromRaw(p); @@ -2403,7 +2413,7 @@ TX.prototype.fromExtended = function fromExtended(data, saveCoins) { coin = p.readVarBytes(); if (coin.length === 0) continue; - coin = bcoin.coin.fromRaw(coin); + coin = Coin.fromRaw(coin); coin.hash = this.inputs[i].prevout.hash; coin.index = this.inputs[i].prevout.index; this.inputs[i].coin = coin; diff --git a/lib/protocol/index.js b/lib/protocol/index.js new file mode 100644 index 00000000..7c3e4dae --- /dev/null +++ b/lib/protocol/index.js @@ -0,0 +1,7 @@ +'use strict'; + +var lazy = require('../utils/lazy')(require, exports); + +lazy('constants', './constants'); +lazy('network', './network'); +lazy('networks', './networks'); diff --git a/lib/protocol/network.js b/lib/protocol/network.js index 14abd439..46363e3c 100644 --- a/lib/protocol/network.js +++ b/lib/protocol/network.js @@ -7,8 +7,7 @@ 'use strict'; -var utils = require('../utils/utils'); -var assert = utils.assert; +var assert = require('assert'); var networks = require('./networks'); /** diff --git a/lib/script/index.js b/lib/script/index.js new file mode 100644 index 00000000..ada86d01 --- /dev/null +++ b/lib/script/index.js @@ -0,0 +1,10 @@ +'use strict'; + +var lazy = require('../utils/lazy')(require, exports); + +lazy('Opcode', './opcode'); +lazy('Program', './program'); +lazy('Script', './script'); +lazy('SigCache', './sigcache'); +lazy('Stack', './stack'); +lazy('Witness', './witness'); diff --git a/lib/script/opcode.js b/lib/script/opcode.js index da147731..4db6c9a5 100644 --- a/lib/script/opcode.js +++ b/lib/script/opcode.js @@ -7,11 +7,13 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = Opcode; + var bn = require('bn.js'); -var constants = bcoin.constants; +var constants = require('../protocol/constants'); var utils = require('../utils/utils'); -var assert = utils.assert; +var Script = require('./script'); +var assert = require('assert'); var opcodes = constants.opcodes; /** @@ -39,7 +41,7 @@ function Opcode(value, data) { */ Opcode.prototype.toRaw = function toRaw(writer) { - return bcoin.script.encode([this], writer); + return Script.encode([this], writer); }; /** @@ -105,7 +107,7 @@ Opcode.fromPush = function fromPush(data) { */ Opcode.fromNumber = function fromNumber(num) { - return Opcode.fromData(bcoin.script.array(num)); + return Opcode.fromData(Script.array(num)); }; /** diff --git a/lib/script/program.js b/lib/script/program.js index 1d3ee8ee..b69ba8d1 100644 --- a/lib/script/program.js +++ b/lib/script/program.js @@ -7,10 +7,11 @@ 'use strict'; -var bcoin = require('../env'); -var constants = bcoin.constants; +module.exports = Program; + +var constants = require('../protocol/constants'); var utils = require('../utils/utils'); -var assert = utils.assert; +var assert = require('assert'); var scriptTypes = constants.scriptTypes; /** diff --git a/lib/script/script.js b/lib/script/script.js index 2a22b088..96817f6a 100644 --- a/lib/script/script.js +++ b/lib/script/script.js @@ -7,23 +7,27 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = Script; + var bn = require('bn.js'); -var constants = bcoin.constants; +var constants = require('../protocol/constants'); var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; +var assert = require('assert'); var BufferWriter = require('../utils/writer'); var BufferReader = require('../utils/reader'); var opcodes = constants.opcodes; var STACK_TRUE = new Buffer([1]); var STACK_FALSE = new Buffer([]); var STACK_NEGATE = new Buffer([0x81]); -var ScriptError = bcoin.errors.ScriptError; +var ScriptError = require('../utils/errors').ScriptError; var scriptTypes = constants.scriptTypes; var Program = require('./program'); var Opcode = require('./opcode'); var Stack = require('./stack'); +var SigCache = require('./sigcache'); +var ec = require('../crypto/ec'); +var Address = require('../primitives/address'); /** * Represents a input or output script. @@ -369,7 +373,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, version) { val = stack.pop(); - if (version == 1 && (flags & constants.flags.VERIFY_MINIMALIF)) { + if (version === 1 && (flags & constants.flags.VERIFY_MINIMALIF)) { if (val.length > 1) throw new ScriptError('MINIMALIF'); @@ -1600,7 +1604,7 @@ Script.fromProgram = function fromProgram(version, data) { Script.prototype.fromAddress = function fromAddress(address) { if (typeof address === 'string') - address = bcoin.address.fromBase58(address); + address = Address.fromBase58(address); if (!address) throw new Error('Unknown address type.'); @@ -1769,7 +1773,7 @@ Script.prototype.getSize = function getSize() { */ Script.prototype.getInputAddress = function getInputAddress() { - return bcoin.address.fromInputScript(this); + return Address.fromInputScript(this); }; /** @@ -1780,7 +1784,7 @@ Script.prototype.getInputAddress = function getInputAddress() { */ Script.prototype.getAddress = function getAddress() { - return bcoin.address.fromScript(this); + return Address.fromScript(this); }; /** @@ -2765,7 +2769,7 @@ Script.isLowDER = function isLowDER(sig) { if (!Script.isSignatureEncoding(sig)) return false; - return bcoin.ec.isLowS(sig.slice(0, -1)); + return ec.isLowS(sig.slice(0, -1)); }; /** @@ -3483,10 +3487,10 @@ Script.checksig = function checksig(msg, sig, key, flags) { if (!(flags & constants.flags.VERIFY_LOW_S)) high = true; - if (bcoin.sigcache) - return bcoin.sigcache.verify(msg, sig.slice(0, -1), key, historical, high); + if (SigCache) + return SigCache.verify(msg, sig.slice(0, -1), key, historical, high); - return bcoin.ec.verify(msg, sig.slice(0, -1), key, historical, high); + return ec.verify(msg, sig.slice(0, -1), key, historical, high); }; /** @@ -3498,7 +3502,7 @@ Script.checksig = function checksig(msg, sig, key, flags) { */ Script.sign = function sign(msg, key, type) { - var sig = bcoin.ec.sign(msg, key); + var sig = ec.sign(msg, key); var p = new BufferWriter(); // Add the sighash type as a single byte @@ -3516,7 +3520,7 @@ Script.sign = function sign(msg, key, type) { */ Script.prototype.fromRaw = function fromRaw(data) { - if (data instanceof bcoin.reader) + if (data instanceof BufferReader) data = data.readVarBytes(); this.raw = data; diff --git a/lib/script/sigcache.js b/lib/script/sigcache.js index 84db1e06..38de3018 100644 --- a/lib/script/sigcache.js +++ b/lib/script/sigcache.js @@ -6,9 +6,9 @@ 'use strict'; -var bcoin = require('../env'); -var utils = bcoin.utils; -var assert = utils.assert; +var utils = require('../utils/utils'); +var ec = require('../crypto/ec'); +var assert = require('assert'); /** * Signature cache. @@ -106,14 +106,14 @@ SigCache.prototype.verify = function verify(msg, sig, key, historical, high) { var hash, result; if (historical || this.size === 0) - return bcoin.ec.verify(msg, sig, key, historical, high); + return ec.verify(msg, sig, key, historical, high); hash = msg.toString('hex'); if (this.has(hash, sig, key)) return true; - result = bcoin.ec.verify(msg, sig, key, historical, high); + result = ec.verify(msg, sig, key, historical, high); if (!result) return false; diff --git a/lib/script/stack.js b/lib/script/stack.js index 9b07ab19..c9b081fb 100644 --- a/lib/script/stack.js +++ b/lib/script/stack.js @@ -7,10 +7,13 @@ 'use strict'; -var bcoin = require('../env'); -var constants = bcoin.constants; +module.exports = Stack; + +var constants = require('../protocol/constants'); var opcodes = constants.opcodes; -var ScriptError = bcoin.errors.ScriptError; +var ScriptError = require('../utils/errors').ScriptError; +var Script = require('./script'); +var Witness = require('./witness'); /** * Represents the stack of a Script during execution. @@ -51,7 +54,7 @@ Stack.prototype.inspect = function inspect() { */ Stack.prototype.toString = function toString() { - return bcoin.witness.format(this.items); + return Witness.format(this.items); }; /** @@ -61,7 +64,7 @@ Stack.prototype.toString = function toString() { */ Stack.prototype.toASM = function toASM(decode) { - return bcoin.script.formatASM(this.items, decode); + return Script.formatASM(this.items, decode); }; /** @@ -73,7 +76,7 @@ Stack.prototype.getRedeem = function getRedeem() { var redeem = this.items[this.items.length - 1]; if (!redeem) return; - return new bcoin.script(redeem); + return new Script(redeem); }; /** @@ -261,7 +264,7 @@ Stack.prototype.ifdup = function ifdup() { if (this.length === 0) throw new ScriptError('INVALID_STACK_OPERATION', opcodes.OP_IFDUP); - if (bcoin.script.bool(this.top(-1))) + if (Script.bool(this.top(-1))) this.push(this.top(-1)); }; @@ -271,7 +274,7 @@ Stack.prototype.ifdup = function ifdup() { */ Stack.prototype.depth = function depth() { - this.push(bcoin.script.array(this.length)); + this.push(Script.array(this.length)); }; /** @@ -357,7 +360,7 @@ Stack.prototype._pickroll = function pickroll(op, flags) { throw new ScriptError('INVALID_STACK_OPERATION', op); val = this.pop(); - n = bcoin.script.num(val, flags).toNumber(); + n = Script.num(val, flags).toNumber(); if (n < 0 || n >= this.length) throw new ScriptError('INVALID_STACK_OPERATION', op); @@ -517,7 +520,7 @@ Stack.prototype.size = function size() { if (this.length < 1) throw new ScriptError('INVALID_STACK_OPERATION', opcodes.OP_SIZE); - this.push(bcoin.script.array(this.top(-1).length)); + this.push(Script.array(this.top(-1).length)); }; /** diff --git a/lib/script/witness.js b/lib/script/witness.js index 5f3f6722..8b38c70f 100644 --- a/lib/script/witness.js +++ b/lib/script/witness.js @@ -7,17 +7,22 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = Witness; + var bn = require('bn.js'); -var constants = bcoin.constants; +var constants = require('../protocol/constants'); var utils = require('../utils/utils'); -var assert = utils.assert; +var assert = require('assert'); var opcodes = constants.opcodes; var STACK_FALSE = new Buffer([]); var STACK_NEGATE = new Buffer([0x81]); var scriptTypes = constants.scriptTypes; var Script = require('./script'); var Opcode = require('./opcode'); +var BufferWriter = require('../utils/writer'); +var BufferReader = require('../utils/reader'); +var Address = require('../primitives/address'); +var Stack = require('./stack'); /** * Refers to the witness field of segregated witness transactions. @@ -159,7 +164,7 @@ Witness.prototype.clone = function clone() { */ Witness.prototype.toStack = function toStack() { - return new bcoin.stack(this.items.slice()); + return new Stack(this.items.slice()); }; /** @@ -185,7 +190,7 @@ Witness.prototype.getInputType = function getInputType() { */ Witness.prototype.getInputAddress = function getInputAddress() { - return bcoin.address.fromWitness(this); + return Address.fromWitness(this); }; /** @@ -301,7 +306,7 @@ Witness.prototype.indexOf = function indexOf(data) { */ Witness.prototype.toRaw = function toRaw(writer) { - var p = bcoin.writer(writer); + var p = BufferWriter(writer); var i; p.writeVarint(this.items.length); @@ -515,7 +520,7 @@ Witness.encodeItem = function encodeItem(data) { */ Witness.prototype.fromRaw = function fromRaw(data) { - var p = bcoin.reader(data); + var p = BufferReader(data); var chunkCount = p.readVarint(); var i; diff --git a/lib/utils/async.js b/lib/utils/async.js index 6e0f90d6..fa9ac425 100644 --- a/lib/utils/async.js +++ b/lib/utils/async.js @@ -9,7 +9,7 @@ var utils = require('../utils/utils'); var spawn = require('../utils/spawn'); var co = spawn.co; -var assert = utils.assert; +var assert = require('assert'); var wait = spawn.wait; var EventEmitter = require('events').EventEmitter; diff --git a/lib/utils/errors.js b/lib/utils/errors.js index f8067eb0..fcaaa41b 100644 --- a/lib/utils/errors.js +++ b/lib/utils/errors.js @@ -7,9 +7,8 @@ 'use strict'; -var bcoin = require('../env'); -var utils = bcoin.utils; -var constants = bcoin.constants; +var utils = require('../utils/utils'); +var constants = require('../protocol/constants'); /** * An error thrown during verification. Can be either diff --git a/lib/utils/index.js b/lib/utils/index.js new file mode 100644 index 00000000..e5f268a6 --- /dev/null +++ b/lib/utils/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./utils'); diff --git a/lib/utils/lazy.js b/lib/utils/lazy.js new file mode 100644 index 00000000..27d6c3e4 --- /dev/null +++ b/lib/utils/lazy.js @@ -0,0 +1,18 @@ +/*! + * lazy.js - lazy loading for bcoin + * Copyright (c) 2016, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/bcoin + */ + +'use strict'; + +module.exports = function lazy(require, exports) { + return function _require(name, path) { + var cache; + exports.__defineGetter__(name, function() { + if (!cache) + cache = require(path); + return cache; + }); + }; +}; diff --git a/lib/utils/locker.js b/lib/utils/locker.js index c5de5011..9f5e2fcb 100644 --- a/lib/utils/locker.js +++ b/lib/utils/locker.js @@ -9,7 +9,7 @@ var EventEmitter = require('events').EventEmitter; var utils = require('../utils/utils'); -var assert = utils.assert; +var assert = require('assert'); /** * Represents a mutex lock for locking asynchronous object methods. diff --git a/lib/utils/reader.js b/lib/utils/reader.js index 0d7ec221..52ded3d7 100644 --- a/lib/utils/reader.js +++ b/lib/utils/reader.js @@ -9,7 +9,7 @@ var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; +var assert = require('assert'); /** * An object that allows reading of buffers in a sane manner. diff --git a/lib/utils/uri.js b/lib/utils/uri.js index e13bfd06..0459c79a 100644 --- a/lib/utils/uri.js +++ b/lib/utils/uri.js @@ -6,15 +6,15 @@ 'use strict'; -var bcoin = require('../env'); var utils = require('../utils/utils'); -var assert = utils.assert; +var Address = require('../primitives/address'); +var assert = require('assert'); function URI(options) { if (!(this instanceof URI)) return new URI(options); - this.address = new bcoin.address(); + this.address = new Address(); this.amount = -1; this.label = null; this.message = null; diff --git a/lib/utils/utils.js b/lib/utils/utils.js index 29c93854..a8ddf286 100644 --- a/lib/utils/utils.js +++ b/lib/utils/utils.js @@ -20,7 +20,7 @@ var native = require('./native'); var bn = require('bn.js'); var util = require('util'); var Number, Math, Date; -var fs; +var fs, lazy; /** * Reference to the global object. @@ -407,15 +407,6 @@ utils.merge = function merge(target) { if (Object.assign) utils.merge = Object.assign; -/** - * Assertion. - * @function - * @param {Boolean} value - Expression. - * @param {String?} message - Optional error message. - */ - -utils.assert = assert; - /** * Safely convert satoshis to a BTC string. * This function explicitly avoids any @@ -2368,3 +2359,29 @@ utils.VerifyResult = function VerifyResult() { this.reason = 'unknown'; this.score = 0; }; + +/** + * Create a lazy loader. + * @param {Function} require + * @param {Object} exports + */ + +utils.lazy = require('./lazy'); + +/* + * Expose other objects. + */ + +lazy = utils.lazy(require, exports); + +lazy('AsyncObject', './async'); +lazy('bloom', './bloom'); +lazy('errors', './errors'); +lazy('ip', './ip'); +lazy('Locker', './locker'); +lazy('LRU', './lru'); +lazy('murmur3', './murmur3'); +lazy('spawn', './spawn'); +lazy('uri', './uri'); +lazy('BufferReader', './reader'); +lazy('BufferWriter', './writer'); diff --git a/lib/utils/writer.js b/lib/utils/writer.js index 381c1e9d..250e6660 100644 --- a/lib/utils/writer.js +++ b/lib/utils/writer.js @@ -9,7 +9,7 @@ var utils = require('../utils/utils'); var crypto = require('../crypto/crypto'); -var assert = utils.assert; +var assert = require('assert'); /* * Constants diff --git a/lib/wallet/account.js b/lib/wallet/account.js index 100b7fda..7ad63462 100644 --- a/lib/wallet/account.js +++ b/lib/wallet/account.js @@ -10,7 +10,7 @@ var Network = require('../protocol/network'); var utils = require('../utils/utils'); var spawn = require('../utils/spawn'); var co = spawn.co; -var assert = utils.assert; +var assert = require('assert'); var BufferReader = require('../utils/reader'); var BufferWriter = require('../utils/writer'); var Path = require('./path'); @@ -350,7 +350,7 @@ Account.prototype.addKey = co(function* addKey(key) { */ Account.prototype._checkKeys = co(function* _checkKeys() { - var ring, hash, paths; + var ring, hash; if (this.initialized || this.type !== Account.types.MULTISIG) return false; @@ -530,7 +530,7 @@ Account.prototype.derivePath = function derivePath(path, master) { Account.prototype.deriveKey = function deriveKey(branch, index, master) { var keys = []; - var i, key, shared, ring, hash; + var i, key, shared, ring; assert(typeof branch === 'number'); diff --git a/lib/wallet/index.js b/lib/wallet/index.js new file mode 100644 index 00000000..2e62fee5 --- /dev/null +++ b/lib/wallet/index.js @@ -0,0 +1,10 @@ +'use strict'; + +var lazy = require('../utils/lazy')(require, exports); + +lazy('Account', './account'); +lazy('Path', './path'); +lazy('TXDB', './txdb'); +lazy('WalletDB', './walletdb'); +lazy('Wallet', './wallet'); +lazy('WalletKey', './walletkey'); diff --git a/lib/wallet/path.js b/lib/wallet/path.js index c2c0b73a..e13065e3 100644 --- a/lib/wallet/path.js +++ b/lib/wallet/path.js @@ -6,9 +6,7 @@ 'use strict'; -var utils = require('../utils/utils'); -var assert = utils.assert; -var constants = require('../protocol/constants'); +var assert = require('assert'); var BufferReader = require('../utils/reader'); var BufferWriter = require('../utils/writer'); var Address = require('../primitives/address'); diff --git a/lib/wallet/txdb.js b/lib/wallet/txdb.js index f65c414a..d7c20b28 100644 --- a/lib/wallet/txdb.js +++ b/lib/wallet/txdb.js @@ -12,7 +12,7 @@ var Locker = require('../utils/locker'); var LRU = require('../utils/lru'); var spawn = require('../utils/spawn'); var co = spawn.co; -var assert = utils.assert; +var assert = require('assert'); var constants = require('../protocol/constants'); var BufferReader = require('../utils/reader'); var BufferWriter = require('../utils/writer'); diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index 658af14b..471c9dc4 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -15,7 +15,7 @@ var Locker = require('../utils/locker'); var spawn = require('../utils/spawn'); var co = spawn.co; var crypto = require('../crypto/crypto'); -var assert = utils.assert; +var assert = require('assert'); var BufferReader = require('../utils/reader'); var BufferWriter = require('../utils/writer'); var TXDB = require('./txdb'); diff --git a/lib/wallet/walletdb.js b/lib/wallet/walletdb.js index 6be947a0..14488703 100644 --- a/lib/wallet/walletdb.js +++ b/lib/wallet/walletdb.js @@ -14,18 +14,18 @@ var Locker = require('../utils/locker'); var LRU = require('../utils/lru'); var co = spawn.co; var crypto = require('../crypto/crypto'); -var assert = utils.assert; +var assert = require('assert'); var constants = require('../protocol/constants'); var Network = require('../protocol/network'); var BufferReader = require('../utils/reader'); var BufferWriter = require('../utils/writer'); var Path = require('./path'); -var Script = require('../script/script'); var Wallet = require('./wallet'); var Account = require('./account'); var ldb = require('../db/ldb'); var Bloom = require('../utils/bloom'); var Logger = require('../node/logger'); +var TX = require('../primitives/tx'); /* * Database Layout: @@ -1312,7 +1312,7 @@ WalletDB.prototype.getPathInfo = co(function* getPathInfo(wallet, tx) { WalletDB.prototype.getTable = co(function* getTable(hashes) { var table = {}; var match = false; - var i, j, keys, values, hash, paths; + var i, hash, paths; for (i = 0; i < hashes.length; i++) { hash = hashes[i]; diff --git a/lib/wallet/walletkey.js b/lib/wallet/walletkey.js index c849ef70..376b5272 100644 --- a/lib/wallet/walletkey.js +++ b/lib/wallet/walletkey.js @@ -11,8 +11,6 @@ var constants = require('../protocol/constants'); var KeyRing = require('../primitives/keyring'); var utils = require('../utils/utils'); var Path = require('./path'); -var Script = require('../script/script'); -var assert = utils.assert; /** * Represents a key ring which amounts to an address. diff --git a/lib/workers/framer.js b/lib/workers/framer.js new file mode 100644 index 00000000..523108b2 --- /dev/null +++ b/lib/workers/framer.js @@ -0,0 +1,146 @@ +/*! + * workers.js - worker processes for bcoin + * Copyright (c) 2014-2015, Fedor Indutny (MIT License) + * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/bcoin + */ + +'use strict'; + +var EventEmitter = require('events').EventEmitter; +var bn = require('bn.js'); +var utils = require('../utils/utils'); +var assert = require('assert'); +var BufferWriter = require('../utils/writer'); +var Block = require('../primitives/block'); +var MTX = require('../primitives/mtx'); +var TX = require('../primitives/tx'); +var Coin = require('../primitives/coin'); +var KeyRing = require('../primitives/keyring'); +var Script = require('../script/script'); +var Witness = require('../script/witness'); +var HD = require('../hd/hd'); +var MinerBlock = require('../miner/minerblock'); + +/** + * Framer + * @constructor + */ + +function Framer() { + if (!(this instanceof Framer)) + return new Framer(); + + EventEmitter.call(this); +} + +utils.inherits(Framer, EventEmitter); + +Framer.prototype.packet = function packet(job, cmd, items) { + var payload = this.body(items); + var packet = new Buffer(25 + payload.length + 1); + + assert(cmd.length < 12); + assert(payload.length <= 0xffffffff); + + packet.writeUInt32LE(0xdeadbeef, 0, true); + packet.writeUInt32LE(job, 4, true); + packet.writeUInt8(cmd.length, 8, true); + packet.write(cmd, 9, 'ascii'); + packet.writeUInt32LE(payload.length, 21, true); + payload.copy(packet, 25); + packet[packet.length - 1] = 0x0a; + + return packet; +}; + +Framer.prototype.body = function body(items) { + return Framer.item(items); +}; + +Framer.item = function _item(item, writer) { + var p = BufferWriter(writer); + var i, keys; + + switch (typeof item) { + case 'string': + p.writeU8(1); + p.writeVarString(item, 'utf8'); + break; + case 'number': + p.writeU8(2); + p.write32(item); + break; + case 'boolean': + p.writeU8(3); + p.writeU8(item ? 1 : 0); + break; + case 'object': + case 'undefined': + if (item == null) { + p.writeU8(0); + } else { + if (item instanceof Block) { + p.writeU8(40); + item.toRaw(p); + } else if (item instanceof MTX) { + p.writeU8(46); + item.toExtended(true, p); + } else if (item instanceof TX) { + p.writeU8(41); + item.toExtended(true, p); + } else if (item instanceof Coin) { + p.writeU8(42); + item.toExtended(p); + } else if (item instanceof MinerBlock) { + p.writeU8(45); + item.toRaw(p); + } else if (item instanceof KeyRing) { + p.writeU8(47); + item.toRaw(p); + } else if (HD.isHD(item)) { + p.writeU8(48); + p.writeBytes(item.toRaw()); + } else if (item instanceof Script) { + p.writeU8(49); + p.writeVarBytes(item.toRaw()); + } else if (item instanceof Witness) { + p.writeU8(50); + item.toRaw(p); + } else if (bn.isBN(item)) { + p.writeU8(10); + p.writeVarBytes(item.toArrayLike(Buffer)); + } else if (Buffer.isBuffer(item)) { + p.writeU8(4); + p.writeVarBytes(item); + } else if (Array.isArray(item)) { + p.writeU8(5); + p.writeVarint(item.length); + for (i = 0; i < item.length; i++) + Framer.item(item[i], p); + } else { + keys = Object.keys(item); + p.writeU8(6); + p.writeVarint(keys.length); + for (i = 0; i < keys.length; i++) { + p.writeVarString(keys[i], 'utf8'); + Framer.item(item[keys[i]], p); + } + } + } + break; + default: + throw new Error('Bad type.'); + } + + if (!writer) + p = p.render(); + + return p; +}; + +/* + * Expose + */ + +module.exports = Framer; diff --git a/lib/workers/index.js b/lib/workers/index.js new file mode 100644 index 00000000..f11a361e --- /dev/null +++ b/lib/workers/index.js @@ -0,0 +1,9 @@ +'use strict'; + +var lazy = require('../utils/lazy')(require, exports); + +lazy('jobs', './jobs'); +lazy('Worker', './worker'); +lazy('Workers', './workers'); +lazy('Parser', './parser'); +lazy('Framer', './framer'); diff --git a/lib/workers/jobs.js b/lib/workers/jobs.js index 94110a52..8d14eaf6 100644 --- a/lib/workers/jobs.js +++ b/lib/workers/jobs.js @@ -6,7 +6,8 @@ 'use strict'; -var bcoin = require('../env'); +var ec = require('../crypto/ec'); +var scrypt = require('../crypto/scrypt'); /** * Jobs to execute within the worker. @@ -97,7 +98,7 @@ jobs.signInput = function signInput(tx, index, key, type) { */ jobs.ecVerify = function ecVerify(msg, sig, key) { - return bcoin.ec.verify(msg, sig, key); + return ec.verify(msg, sig, key); }; /** @@ -110,7 +111,7 @@ jobs.ecVerify = function ecVerify(msg, sig, key) { */ jobs.ecSign = function ecSign(msg, key) { - return bcoin.ec.sign(msg, key); + return ec.sign(msg, key); }; /** @@ -140,7 +141,6 @@ jobs.mine = function mine(attempt) { * @returns {Buffer} */ -jobs.scrypt = function scrypt(passwd, salt, N, r, p, len) { - var scrypt = require('../crypto/scrypt'); +jobs.scrypt = function _scrypt(passwd, salt, N, r, p, len) { return scrypt(passwd, salt, N >>> 0, r >>> 0, p >>> 0, len); }; diff --git a/lib/workers/parser.js b/lib/workers/parser.js new file mode 100644 index 00000000..cdea2eed --- /dev/null +++ b/lib/workers/parser.js @@ -0,0 +1,225 @@ +/*! + * workers.js - worker processes for bcoin + * Copyright (c) 2014-2015, Fedor Indutny (MIT License) + * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/bcoin + */ + +'use strict'; + +var EventEmitter = require('events').EventEmitter; +var bn = require('bn.js'); +var utils = require('../utils/utils'); +var assert = require('assert'); +var BufferReader = require('../utils/reader'); +var Block = require('../primitives/block'); +var MTX = require('../primitives/mtx'); +var TX = require('../primitives/tx'); +var Coin = require('../primitives/coin'); +var KeyRing = require('../primitives/keyring'); +var Script = require('../script/script'); +var Witness = require('../script/witness'); +var HD = require('../hd/hd'); +var MinerBlock = require('../miner/minerblock'); + +/** + * Parser + * @constructor + */ + +function Parser() { + if (!(this instanceof Parser)) + return new Parser(); + + EventEmitter.call(this); + + this.waiting = 25; + this.packet = null; + this.pending = []; + this.total = 0; +} + +utils.inherits(Parser, EventEmitter); + +Parser.prototype.feed = function feed(data) { + var chunk; + + this.total += data.length; + this.pending.push(data); + + while (this.total >= this.waiting) { + chunk = this.read(this.waiting); + this.parse(chunk); + } +}; + +Parser.prototype.read = function read(size) { + var pending, chunk, off, len; + + assert(this.total >= size, 'Reading too much.'); + + if (size === 0) + return new Buffer(0); + + pending = this.pending[0]; + + if (pending.length > size) { + chunk = pending.slice(0, size); + this.pending[0] = pending.slice(size); + this.total -= chunk.length; + return chunk; + } + + if (pending.length === size) { + chunk = this.pending.shift(); + this.total -= chunk.length; + return chunk; + } + + chunk = new Buffer(size); + off = 0; + len = 0; + + while (off < chunk.length) { + pending = this.pending[0]; + len = pending.copy(chunk, off); + if (len === pending.length) + this.pending.shift(); + else + this.pending[0] = pending.slice(len); + off += len; + } + + assert.equal(off, chunk.length); + + this.total -= chunk.length; + + return chunk; +}; + +Parser.prototype.parse = function parse(data) { + var packet = this.packet; + + if (!packet) { + try { + packet = this.parseHeader(data); + } catch (e) { + this.emit('error', e); + return; + } + + this.packet = packet; + this.waiting = packet.size + 1; + + return; + } + + this.waiting = 25; + this.packet = null; + + try { + packet.items = this.parseBody(data); + } catch (e) { + this.emit('error', e); + return; + } + + if (data[data.length - 1] !== 0x0a) { + this.emit('error', new Error('No trailing newline.')); + return; + } + + this.emit('packet', packet); +}; + +Parser.prototype.parseHeader = function parseHeader(data) { + var magic, job, len, cmd, size; + + magic = data.readUInt32LE(0, true); + + if (magic !== 0xdeadbeef) + throw new Error('Bad magic number: ' + magic.toString(16)); + + job = data.readUInt32LE(4, true); + + len = data[8]; + cmd = data.toString('ascii', 9, 9 + len); + + size = data.readUInt32LE(21, true); + + return new Packet(job, cmd, size); +}; + +Parser.prototype.parseBody = function parseBody(data) { + return Parser.parseItem(data); +}; + +Parser.parseItem = function parseItem(data) { + var p = BufferReader(data); + var i, count, items; + + switch (p.readU8()) { + case 0: + return null; + case 1: + return p.readVarString('utf8'); + case 2: + return p.read32(); + case 3: + return p.readU8() === 1; + case 4: + return p.readVarBytes(); + case 5: + items = []; + count = p.readVarint(); + for (i = 0; i < count; i++) + items.push(Parser.parseItem(p)); + return items; + case 6: + items = {}; + count = p.readVarint(); + for (i = 0; i < count; i++) + items[p.readVarString('utf8')] = Parser.parseItem(p); + return items; + case 10: + return new bn(p.readVarBytes()); + case 40: + return Block.fromRaw(p); + case 41: + return TX.fromExtended(p, true); + case 42: + return Coin.fromExtended(p); + case 45: + return MinerBlock.fromRaw(p); + case 46: + return MTX.fromExtended(p, true); + case 47: + return KeyRing.fromRaw(p); + case 48: + return HD.fromRaw(p.readBytes(82)); + case 49: + return Script.fromRaw(p.readVarBytes()); + case 50: + return Witness.fromRaw(p); + default: + throw new Error('Bad type.'); + } +}; + +/** + * Packet + * @constructor + */ + +function Packet(job, cmd, size) { + this.job = job; + this.cmd = cmd; + this.size = size; + this.items = null; +} + +/* + * Expose + */ + +module.exports = Parser; diff --git a/lib/workers/workers.js b/lib/workers/workers.js index a28643d6..9ae6a197 100644 --- a/lib/workers/workers.js +++ b/lib/workers/workers.js @@ -7,17 +7,17 @@ 'use strict'; -var bcoin = require('../env'); +module.exports = Workers; + var EventEmitter = require('events').EventEmitter; -var bn = require('bn.js'); var utils = require('../utils/utils'); var spawn = require('../utils/spawn'); var co = spawn.co; var global = utils.global; -var assert = utils.assert; -var BufferWriter = require('../utils/writer'); -var BufferReader = require('../utils/reader'); +var Network = require('../protocol/network'); var jobs = require('./jobs'); +var Parser = require('./parser'); +var Framer = require('./framer'); /** * A worker pool. @@ -826,329 +826,6 @@ Master.listen = function listen(options) { return master; }; -/** - * Framer - * @constructor - */ - -function Framer() { - if (!(this instanceof Framer)) - return new Framer(); - - EventEmitter.call(this); -} - -utils.inherits(Framer, EventEmitter); - -Framer.prototype.packet = function packet(job, cmd, items) { - var payload = this.body(items); - var packet = new Buffer(25 + payload.length + 1); - - assert(cmd.length < 12); - assert(payload.length <= 0xffffffff); - - packet.writeUInt32LE(0xdeadbeef, 0, true); - packet.writeUInt32LE(job, 4, true); - packet.writeUInt8(cmd.length, 8, true); - packet.write(cmd, 9, 'ascii'); - packet.writeUInt32LE(payload.length, 21, true); - payload.copy(packet, 25); - packet[packet.length - 1] = 0x0a; - - return packet; -}; - -Framer.prototype.body = function body(items) { - return Framer.item(items); -}; - -Framer.item = function _item(item, writer) { - var p = BufferWriter(writer); - var i, keys; - - switch (typeof item) { - case 'string': - p.writeU8(1); - p.writeVarString(item, 'utf8'); - break; - case 'number': - p.writeU8(2); - p.write32(item); - break; - case 'boolean': - p.writeU8(3); - p.writeU8(item ? 1 : 0); - break; - case 'object': - case 'undefined': - if (item == null) { - p.writeU8(0); - } else { - if (item instanceof bcoin.block) { - p.writeU8(40); - item.toRaw(p); - } else if (item instanceof bcoin.mtx) { - p.writeU8(46); - item.toExtended(true, p); - } else if (item instanceof bcoin.tx) { - p.writeU8(41); - item.toExtended(true, p); - } else if (item instanceof bcoin.coin) { - p.writeU8(42); - item.toExtended(p); - } else if (item instanceof bcoin.chainentry) { - p.writeU8(43); - item.toRaw(p); - } else if (item instanceof bcoin.mempoolentry) { - p.writeU8(44); - item.toRaw(p); - } else if (item instanceof bcoin.minerblock) { - p.writeU8(45); - item.toRaw(p); - } else if (item instanceof bcoin.keyring) { - p.writeU8(47); - item.toRaw(p); - } else if (bcoin.hd.isHD(item)) { - p.writeU8(48); - p.writeBytes(item.toRaw()); - } else if (item instanceof bcoin.script) { - p.writeU8(49); - p.writeVarBytes(item.toRaw()); - } else if (item instanceof bcoin.witness) { - p.writeU8(50); - item.toRaw(p); - } else if (bn.isBN(item)) { - p.writeU8(10); - p.writeVarBytes(item.toArrayLike(Buffer)); - } else if (Buffer.isBuffer(item)) { - p.writeU8(4); - p.writeVarBytes(item); - } else if (Array.isArray(item)) { - p.writeU8(5); - p.writeVarint(item.length); - for (i = 0; i < item.length; i++) - Framer.item(item[i], p); - } else { - keys = Object.keys(item); - p.writeU8(6); - p.writeVarint(keys.length); - for (i = 0; i < keys.length; i++) { - p.writeVarString(keys[i], 'utf8'); - Framer.item(item[keys[i]], p); - } - } - } - break; - default: - throw new Error('Bad type.'); - } - - if (!writer) - p = p.render(); - - return p; -}; - -/** - * Parser - * @constructor - */ - -function Parser() { - if (!(this instanceof Parser)) - return new Parser(); - - EventEmitter.call(this); - - this.waiting = 25; - this.packet = null; - this.pending = []; - this.total = 0; -} - -utils.inherits(Parser, EventEmitter); - -Parser.prototype.feed = function feed(data) { - var chunk; - - this.total += data.length; - this.pending.push(data); - - while (this.total >= this.waiting) { - chunk = this.read(this.waiting); - this.parse(chunk); - } -}; - -Parser.prototype.read = function read(size) { - var pending, chunk, off, len; - - assert(this.total >= size, 'Reading too much.'); - - if (size === 0) - return new Buffer(0); - - pending = this.pending[0]; - - if (pending.length > size) { - chunk = pending.slice(0, size); - this.pending[0] = pending.slice(size); - this.total -= chunk.length; - return chunk; - } - - if (pending.length === size) { - chunk = this.pending.shift(); - this.total -= chunk.length; - return chunk; - } - - chunk = new Buffer(size); - off = 0; - len = 0; - - while (off < chunk.length) { - pending = this.pending[0]; - len = pending.copy(chunk, off); - if (len === pending.length) - this.pending.shift(); - else - this.pending[0] = pending.slice(len); - off += len; - } - - assert.equal(off, chunk.length); - - this.total -= chunk.length; - - return chunk; -}; - -Parser.prototype.parse = function parse(data) { - var packet = this.packet; - - if (!packet) { - try { - packet = this.parseHeader(data); - } catch (e) { - this.emit('error', e); - return; - } - - this.packet = packet; - this.waiting = packet.size + 1; - - return; - } - - this.waiting = 25; - this.packet = null; - - try { - packet.items = this.parseBody(data); - } catch (e) { - this.emit('error', e); - return; - } - - if (data[data.length - 1] !== 0x0a) { - this.emit('error', new Error('No trailing newline.')); - return; - } - - this.emit('packet', packet); -}; - -Parser.prototype.parseHeader = function parseHeader(data) { - var magic, job, len, cmd, size; - - magic = data.readUInt32LE(0, true); - - if (magic !== 0xdeadbeef) - throw new Error('Bad magic number: ' + magic.toString(16)); - - job = data.readUInt32LE(4, true); - - len = data[8]; - cmd = data.toString('ascii', 9, 9 + len); - - size = data.readUInt32LE(21, true); - - return new Packet(job, cmd, size); -}; - -Parser.prototype.parseBody = function parseBody(data) { - return Parser.parseItem(data); -}; - -Parser.parseItem = function parseItem(data) { - var p = BufferReader(data); - var i, count, items; - - switch (p.readU8()) { - case 0: - return null; - case 1: - return p.readVarString('utf8'); - case 2: - return p.read32(); - case 3: - return p.readU8() === 1; - case 4: - return p.readVarBytes(); - case 5: - items = []; - count = p.readVarint(); - for (i = 0; i < count; i++) - items.push(Parser.parseItem(p)); - return items; - case 6: - items = {}; - count = p.readVarint(); - for (i = 0; i < count; i++) - items[p.readVarString('utf8')] = Parser.parseItem(p); - return items; - case 10: - return new bn(p.readVarBytes()); - case 40: - return bcoin.block.fromRaw(p); - case 41: - return bcoin.tx.fromExtended(p, true); - case 42: - return bcoin.coin.fromExtended(p); - case 43: - return bcoin.chainentry.fromRaw(null, p); - case 44: - return bcoin.mempoolentry.fromRaw(p); - case 45: - return bcoin.minerblock.fromRaw(p); - case 46: - return bcoin.mtx.fromExtended(p, true); - case 47: - return bcoin.keyring.fromRaw(p); - case 48: - return bcoin.hd.fromRaw(p.readBytes(82)); - case 49: - return bcoin.script.fromRaw(p.readVarBytes()); - case 50: - return bcoin.witness.fromRaw(p); - default: - throw new Error('Bad type.'); - } -}; - -/** - * Packet - * @constructor - */ - -function Packet(job, cmd, size) { - this.job = job; - this.cmd = cmd; - this.size = size; - this.items = null; -} - /* * Helpers */ @@ -1179,7 +856,7 @@ function fromError(err) { * Default */ -Workers.global = new Workers(); +Workers.pool = new Workers(); Workers.enabled = false; Workers.set = function set(options) { @@ -1187,10 +864,10 @@ Workers.set = function set(options) { this.enabled = options.useWorkers; if (utils.isNumber(options.maxWorkers)) - this.global.size = options.maxWorkers; + this.pool.size = options.maxWorkers; if (utils.isNumber(options.workerTimeout)) - this.global.timeout = options.workerTimeout; + this.pool.timeout = options.workerTimeout; if (utils.isBrowser && this.enabled) { this.enabled = typeof global.Worker === 'function' diff --git a/test/bip70-test.js b/test/bip70-test.js index 1737c014..8e894874 100644 --- a/test/bip70-test.js +++ b/test/bip70-test.js @@ -9,7 +9,7 @@ var network = bcoin.networks; var assert = require('assert'); var tests = require('./data/bip70.json'); var bip70 = require('../lib/bip70/bip70'); -var x509 = require('../lib/bip70/x509'); +var x509 = bip70.x509; tests.valid = new Buffer(tests.valid, 'hex'); tests.invalid = new Buffer(tests.invalid, 'hex'); diff --git a/test/http-test.js b/test/http-test.js index cf556aa5..eb93d97c 100644 --- a/test/http-test.js +++ b/test/http-test.js @@ -43,7 +43,7 @@ describe('HTTP', function() { db: 'memory' }); - var wallet = new bcoin.http.wallet({ + var wallet = new bcoin.http.Wallet({ network: 'regtest', apiKey: 'foo' }); diff --git a/test/script-test.js b/test/script-test.js index e7955faa..03e82daf 100644 --- a/test/script-test.js +++ b/test/script-test.js @@ -380,7 +380,7 @@ describe('Script', function() { assert.equal(err.code, expected); return; } - utils.assert.ifError(err); + assert.ifError(err); assert(res); }); }); diff --git a/vendor/ip.js b/vendor/ip.js index 21270a65..85ee7f00 100644 --- a/vendor/ip.js +++ b/vendor/ip.js @@ -377,7 +377,7 @@ ip.address = function(name, family) { var os; try { - os = require('o' + 's'); + os = require('os'); } catch (e) { return '127.0.0.1'; }