From e42c497a3c9afe67c86ba0a602b5a0e9bd66e604 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Tue, 23 Dec 2014 15:08:20 +1100 Subject: [PATCH 1/2] package: use typeforce --- package.json | 3 ++- src/address.js | 4 ++-- src/ecdsa.js | 6 +++--- src/eckey.js | 4 ++-- src/ecpubkey.js | 6 +++--- src/ecsignature.js | 6 +++--- src/hdnode.js | 6 +++--- src/script.js | 8 ++++---- src/scripts.js | 16 ++++++++-------- src/transaction.js | 22 +++++++++++----------- src/types.js | 40 ---------------------------------------- src/wallet.js | 10 +++++----- test/types.js | 28 ---------------------------- 13 files changed, 46 insertions(+), 113 deletions(-) delete mode 100644 src/types.js delete mode 100644 test/types.js diff --git a/package.json b/package.json index 9880116..1ee96bd 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,8 @@ "bigi": "^1.1.0", "bs58check": "1.0.3", "crypto-browserify": "^3.2.6", - "ecurve": "1.0.0" + "ecurve": "1.0.0", + "typeforce": "0.0.2" }, "devDependencies": { "async": "^0.9.0", diff --git a/src/address.js b/src/address.js index cc6264f..be2b239 100644 --- a/src/address.js +++ b/src/address.js @@ -1,6 +1,6 @@ var assert = require('assert') var base58check = require('bs58check') -var enforceType = require('./types') +var typeForce = require('typeforce') var networks = require('./networks') var scripts = require('./scripts') @@ -14,7 +14,7 @@ function findScriptTypeByVersion(version) { } function Address(hash, version) { - enforceType('Buffer', hash) + typeForce('Buffer', hash) assert.strictEqual(hash.length, 20, 'Invalid hash length') assert.strictEqual(version & 0xff, version, 'Invalid version byte') diff --git a/src/ecdsa.js b/src/ecdsa.js index e3343fa..28ba1b4 100644 --- a/src/ecdsa.js +++ b/src/ecdsa.js @@ -1,6 +1,6 @@ var assert = require('assert') var crypto = require('crypto') -var enforceType = require('./types') +var typeForce = require('typeforce') var BigInteger = require('bigi') var ECSignature = require('./ecsignature') @@ -10,8 +10,8 @@ var ONE = new Buffer([1]) // https://tools.ietf.org/html/rfc6979#section-3.2 function deterministicGenerateK(curve, hash, d) { - enforceType('Buffer', hash) - enforceType(BigInteger, d) + typeForce('Buffer', hash) + typeForce('BigInteger', d) // sanity check assert.equal(hash.length, 32, 'Hash must be 256 bit') diff --git a/src/eckey.js b/src/eckey.js index 501384d..74ba93c 100644 --- a/src/eckey.js +++ b/src/eckey.js @@ -2,7 +2,7 @@ var assert = require('assert') var base58check = require('bs58check') var crypto = require('crypto') var ecdsa = require('./ecdsa') -var enforceType = require('./types') +var typeForce = require('typeforce') var networks = require('./networks') var BigInteger = require('bigi') @@ -50,7 +50,7 @@ ECKey.makeRandom = function(compressed, rng) { rng = rng || crypto.randomBytes var buffer = rng(32) - enforceType('Buffer', buffer) + typeForce('Buffer', buffer) assert.equal(buffer.length, 32, 'Expected 256-bit Buffer from RNG') var d = BigInteger.fromBuffer(buffer) diff --git a/src/ecpubkey.js b/src/ecpubkey.js index e2b25bc..860e415 100644 --- a/src/ecpubkey.js +++ b/src/ecpubkey.js @@ -1,6 +1,6 @@ var crypto = require('./crypto') var ecdsa = require('./ecdsa') -var enforceType = require('./types') +var typeForce = require('typeforce') var networks = require('./networks') var Address = require('./address') @@ -11,8 +11,8 @@ var secp256k1 = ecurve.getCurveByName('secp256k1') function ECPubKey(Q, compressed) { if (compressed === undefined) compressed = true - enforceType(ecurve.Point, Q) - enforceType('Boolean', compressed) + typeForce('Point', Q) + typeForce('Boolean', compressed) this.compressed = compressed this.Q = Q diff --git a/src/ecsignature.js b/src/ecsignature.js index 7b71c61..073d7f1 100644 --- a/src/ecsignature.js +++ b/src/ecsignature.js @@ -1,11 +1,11 @@ var assert = require('assert') -var enforceType = require('./types') +var typeForce = require('typeforce') var BigInteger = require('bigi') function ECSignature(r, s) { - enforceType(BigInteger, r) - enforceType(BigInteger, s) + typeForce('BigInteger', r) + typeForce('BigInteger', s) this.r = r this.s = s diff --git a/src/hdnode.js b/src/hdnode.js index 03e5bb1..e81dc4e 100644 --- a/src/hdnode.js +++ b/src/hdnode.js @@ -2,7 +2,7 @@ var assert = require('assert') var base58check = require('bs58check') var bcrypto = require('./crypto') var crypto = require('crypto') -var enforceType = require('./types') +var typeForce = require('typeforce') var networks = require('./networks') var BigInteger = require('bigi') @@ -29,7 +29,7 @@ function findBIP32NetworkByVersion(version) { function HDNode(K, chainCode, network) { network = network || networks.bitcoin - enforceType('Buffer', chainCode) + typeForce('Buffer', chainCode) assert.equal(chainCode.length, 32, 'Expected chainCode length of 32, got ' + chainCode.length) assert(network.bip32, 'Unknown BIP32 constants for network') @@ -53,7 +53,7 @@ HDNode.HIGHEST_BIT = 0x80000000 HDNode.LENGTH = 78 HDNode.fromSeedBuffer = function(seed, network) { - enforceType('Buffer', seed) + typeForce('Buffer', seed) assert(seed.length >= 16, 'Seed should be at least 128 bits') assert(seed.length <= 64, 'Seed should be at most 512 bits') diff --git a/src/script.js b/src/script.js index d3afc70..2283495 100644 --- a/src/script.js +++ b/src/script.js @@ -1,12 +1,12 @@ var assert = require('assert') var bufferutils = require('./bufferutils') var crypto = require('./crypto') -var enforceType = require('./types') +var typeForce = require('typeforce') var opcodes = require('./opcodes') function Script(buffer, chunks) { - enforceType('Buffer', buffer) - enforceType('Array', chunks) + typeForce('Buffer', buffer) + typeForce('Array', chunks) this.buffer = buffer this.chunks = chunks @@ -56,7 +56,7 @@ Script.fromBuffer = function(buffer) { } Script.fromChunks = function(chunks) { - enforceType('Array', chunks) + typeForce('Array', chunks) var bufferSize = chunks.reduce(function(accum, chunk) { if (Buffer.isBuffer(chunk)) { diff --git a/src/scripts.js b/src/scripts.js index 0ffb1e0..33f51ca 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -1,5 +1,5 @@ var assert = require('assert') -var enforceType = require('./types') +var typeForce = require('typeforce') var ops = require('./opcodes') var ecurve = require('ecurve') @@ -117,7 +117,7 @@ function isNullDataOutput(script) { } function classifyOutput(script) { - enforceType(Script, script) + typeForce('Script', script) if (isPubKeyHashOutput(script)) { return 'pubkeyhash' @@ -135,7 +135,7 @@ function classifyOutput(script) { } function classifyInput(script) { - enforceType(Script, script) + typeForce('Script', script) if (isPubKeyHashInput(script)) { return 'pubkeyhash' @@ -161,7 +161,7 @@ function pubKeyOutput(pubKey) { // OP_DUP OP_HASH160 {pubKeyHash} OP_EQUALVERIFY OP_CHECKSIG function pubKeyHashOutput(hash) { - enforceType('Buffer', hash) + typeForce('Buffer', hash) return Script.fromChunks([ ops.OP_DUP, @@ -174,7 +174,7 @@ function pubKeyHashOutput(hash) { // OP_HASH160 {scriptHash} OP_EQUAL function scriptHashOutput(hash) { - enforceType('Buffer', hash) + typeForce('Buffer', hash) return Script.fromChunks([ ops.OP_HASH160, @@ -185,7 +185,7 @@ function scriptHashOutput(hash) { // m [pubKeys ...] n OP_CHECKMULTISIG function multisigOutput(m, pubKeys) { - enforceType('Array', pubKeys) + typeForce('Array', pubKeys) assert(pubKeys.length >= m, 'Not enough pubKeys provided') @@ -204,14 +204,14 @@ function multisigOutput(m, pubKeys) { // {signature} function pubKeyInput(signature) { - enforceType('Buffer', signature) + typeForce('Buffer', signature) return Script.fromChunks([signature]) } // {signature} {pubKey} function pubKeyHashInput(signature, pubKey) { - enforceType('Buffer', signature) + typeForce('Buffer', signature) return Script.fromChunks([signature, pubKey.toBuffer()]) } diff --git a/src/transaction.js b/src/transaction.js index 167126c..a952dbb 100644 --- a/src/transaction.js +++ b/src/transaction.js @@ -1,7 +1,7 @@ var assert = require('assert') var bufferutils = require('./bufferutils') var crypto = require('./crypto') -var enforceType = require('./types') +var typeForce = require('typeforce') var opcodes = require('./opcodes') var scripts = require('./scripts') @@ -96,7 +96,7 @@ Transaction.prototype.addInput = function(hash, index, sequence, script) { if (sequence === undefined || sequence === null) { sequence = Transaction.DEFAULT_SEQUENCE } - + script = script || Script.EMPTY if (typeof hash === 'string') { @@ -108,10 +108,10 @@ Transaction.prototype.addInput = function(hash, index, sequence, script) { } - enforceType('Buffer', hash) - enforceType('Number', index) - enforceType('Number', sequence) - enforceType(Script, script) + typeForce('Buffer', hash) + typeForce('Number', index) + typeForce('Number', sequence) + typeForce('Script', script) assert.equal(hash.length, 32, 'Expected hash length of 32, got ' + hash.length) @@ -144,8 +144,8 @@ Transaction.prototype.addOutput = function(scriptPubKey, value) { scriptPubKey = scriptPubKey.toOutputScript() } - enforceType(Script, scriptPubKey) - enforceType('Number', value) + typeForce('Script', scriptPubKey) + typeForce('Number', value) // Add the output and return the output's index return (this.outs.push({ @@ -197,9 +197,9 @@ Transaction.prototype.hashForSignature = function(inIndex, prevOutScript, hashTy prevOutScript = tmp } - enforceType('Number', inIndex) - enforceType(Script, prevOutScript) - enforceType('Number', hashType) + typeForce('Number', inIndex) + typeForce('Script', prevOutScript) + typeForce('Number', hashType) assert(inIndex >= 0, 'Invalid vin index') assert(inIndex < this.ins.length, 'Invalid vin index') diff --git a/src/types.js b/src/types.js deleted file mode 100644 index 5f885d0..0000000 --- a/src/types.js +++ /dev/null @@ -1,40 +0,0 @@ -module.exports = function enforce(type, value) { - switch (type) { - case 'Array': { - if (Array.isArray(value)) return - break - } - - case 'Boolean': { - if (typeof value === 'boolean') return - break - } - - case 'Buffer': { - if (Buffer.isBuffer(value)) return - break - } - - case 'Number': { - if (typeof value === 'number') return - break - } - - case 'String': { - if (typeof value === 'string') return - break - } - - default: { - if (getName(value.constructor) === getName(type)) return - } - } - - throw new TypeError('Expected ' + (getName(type) || type) + ', got ' + value) -} - -function getName(fn) { - // Why not fn.name: https://kangax.github.io/compat-table/es6/#function_name_property - var match = fn.toString().match(/function (.*?)\(/) - return match ? match[1] : null -} diff --git a/src/wallet.js b/src/wallet.js index f7068ff..3e3ab77 100644 --- a/src/wallet.js +++ b/src/wallet.js @@ -1,7 +1,7 @@ var assert = require('assert') var bufferutils = require('./bufferutils') var crypto = require('crypto') -var enforceType = require('./types') +var typeForce = require('typeforce') var networks = require('./networks') var Address = require('./address') @@ -303,9 +303,9 @@ Wallet.prototype.setUnspentOutputs = function(unspents) { index = unspent.outputIndex } - enforceType('String', txId) - enforceType('Number', index) - enforceType('Number', unspent.value) + typeForce('String', txId) + typeForce('Number', index) + typeForce('Number', unspent.value) assert.equal(txId.length, 64, 'Expected valid txId, got ' + txId) assert.doesNotThrow(function() { Address.fromBase58Check(unspent.address) }, 'Expected Base58 Address, got ' + unspent.address) @@ -313,7 +313,7 @@ Wallet.prototype.setUnspentOutputs = function(unspents) { // FIXME: remove branch in 2.0.0 if (unspent.confirmations !== undefined) { - enforceType('Number', unspent.confirmations) + typeForce('Number', unspent.confirmations) } var txHash = bufferutils.reverse(new Buffer(txId, 'hex')) diff --git a/test/types.js b/test/types.js deleted file mode 100644 index fe1d149..0000000 --- a/test/types.js +++ /dev/null @@ -1,28 +0,0 @@ -var assert = require('assert') -var enforceType = require('../src/types') - -function CustomType() { return "ensure non-greedy match".toUpperCase() } - -var types = ['Array', 'Boolean', 'Buffer', 'Number', 'String', CustomType] -var values = [[], true, new Buffer(1), 1234, 'foobar', new CustomType()] - -describe('enforceType', function() { - types.forEach(function(type, i) { - describe(type, function() { - values.forEach(function(value, j) { - if (j === i) { - it('passes for ' + types[j], function() { - enforceType(type, value) - }) - - } else { - it('fails for ' + types[j], function() { - assert.throws(function() { - enforceType(type, value) - }, new RegExp('Expected ' + (type.name || type) + ', got ')) - }) - } - }) - }) - }) -}) From 0524ced98464c4643366f77042da1e8fe2a86af1 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Tue, 23 Dec 2014 15:30:14 +1100 Subject: [PATCH 2/2] scripts: enforce pubKeys as type ECPubKey --- src/scripts.js | 2 +- test/scripts.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scripts.js b/src/scripts.js index 33f51ca..606e14b 100644 --- a/src/scripts.js +++ b/src/scripts.js @@ -185,7 +185,7 @@ function scriptHashOutput(hash) { // m [pubKeys ...] n OP_CHECKMULTISIG function multisigOutput(m, pubKeys) { - typeForce('Array', pubKeys) + typeForce(['ECPubKey'], pubKeys) assert(pubKeys.length >= m, 'Not enough pubKeys provided') diff --git a/test/scripts.js b/test/scripts.js index 8405cd5..ac35a65 100644 --- a/test/scripts.js +++ b/test/scripts.js @@ -168,7 +168,7 @@ describe('Scripts', function() { }) fixtures.invalid.multisigOutput.forEach(function(f) { - var pubKeys = f.pubKeys.map(function(p) { return new Buffer(p, 'hex') }) + var pubKeys = f.pubKeys.map(ECPubKey.fromHex) it('throws on ' + f.exception, function() { assert.throws(function() {