From 5091f69038604d091ce6492373737cfff261e0f9 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 5 Dec 2016 17:24:18 -0800 Subject: [PATCH] wallet/http: send address validation. --- lib/http/server.js | 55 +++++++++++++++++++++++++++----------------- lib/wallet/wallet.js | 25 +++++++++++--------- 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/lib/http/server.js b/lib/http/server.js index 75c59244..133b90e7 100644 --- a/lib/http/server.js +++ b/lib/http/server.js @@ -333,20 +333,24 @@ HTTPServer.prototype._init = function _init() { if (params.subtractFee != null) { if (typeof params.subtractFee === 'number') { options.subtractFee = params.subtractFee; - enforce(util.isUInt32(options.subtractFee), 'subtractFee must be a number.'); + enforce(util.isUInt32(options.subtractFee), + 'subtractFee must be a number.'); } else { options.subtractFee = params.subtractFee; - enforce(typeof options.subtractFee === 'boolean', 'subtractFee must be a boolean.'); + enforce(typeof options.subtractFee === 'boolean', + 'subtractFee must be a boolean.'); } } if (params.watchOnly != null) { - enforce(typeof params.watchOnly === 'boolean', 'watchOnly must be a boolean.'); + enforce(typeof params.watchOnly === 'boolean', + 'watchOnly must be a boolean.'); options.watchOnly = params.watchOnly; } if (params.accountKey) { - enforce(typeof params.accountKey === 'string', 'accountKey must be a string.'); + enforce(typeof params.accountKey === 'string', + 'accountKey must be a string.'); options.accountKey = HD.fromBase58(params.accountKey); } @@ -356,7 +360,8 @@ HTTPServer.prototype._init = function _init() { } if (params.witness != null) { - enforce(typeof params.witness === 'boolean', 'witness must be a boolean.'); + enforce(typeof params.witness === 'boolean', + 'witness must be a boolean.'); options.witness = params.witness; } @@ -366,22 +371,26 @@ HTTPServer.prototype._init = function _init() { for (i = 0; i < params.outputs.length; i++) { output = params.outputs[i]; - enforce(output && typeof output === 'object', 'Output must be an object.'); + enforce(output && typeof output === 'object', + 'Output must be an object.'); - if (output.address) - enforce(typeof output.address === 'string', 'Address must be a string.'); - else if (output.script) - enforce(typeof output.script === 'string', 'Script must be a string.'); - else + if (output.address) { + enforce(typeof output.address === 'string', + 'Address must be a string.'); + output.address = Address.fromBase58(output.address); + enforce(output.address.network === this.network, + 'Wrong network for address.'); + } else if (output.script) { + enforce(typeof output.script === 'string', + 'Script must be a string.'); + output.script = Script.fromRaw(output.script, 'hex'); + } else { enforce(false, 'No address or script present.'); + } options.outputs.push({ - address: output.address - ? Address.fromBase58(output.address) - : null, - script: output.script - ? Script.fromRaw(output.script, 'hex') - : null, + address: output.address || null, + script: output.script || null, value: Amount.value(output.value) }); } @@ -396,7 +405,8 @@ HTTPServer.prototype._init = function _init() { address = Address.fromBase58(address); } } else { - enforce(typeof params.address === 'string', 'Address must be a string.'); + enforce(typeof params.address === 'string', + 'Address must be a string.'); options.address = Address.fromBase58(params.address); } } @@ -405,7 +415,8 @@ HTTPServer.prototype._init = function _init() { if (typeof params.tx === 'object') { options.tx = TX.fromJSON(params.tx); } else { - enforce(typeof params.tx === 'string', 'TX must be a hex string.'); + enforce(typeof params.tx === 'string', + 'TX must be a hex string.'); options.tx = TX.fromRaw(params.tx, 'hex'); } } @@ -415,7 +426,8 @@ HTTPServer.prototype._init = function _init() { options.account = params.account; enforce(util.isUInt32(options.account), 'Account must be a number.'); } else { - enforce(typeof params.account === 'string', 'Account must be a string.'); + enforce(typeof params.account === 'string', + 'Account must be a string.'); options.account = params.account; } } @@ -458,7 +470,8 @@ HTTPServer.prototype._init = function _init() { } if (params.passphrase) { - enforce(typeof params.passphrase === 'string', 'Passphrase must be a string.'); + enforce(typeof params.passphrase === 'string', + 'Passphrase must be a string.'); enforce(params.passphrase.length > 0, 'Passphrase must be a string.'); options.passphrase = params.passphrase; } diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index e6be9552..6425a020 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -26,6 +26,7 @@ var Address = require('../primitives/address'); var MTX = require('../primitives/mtx'); var WalletKey = require('./walletkey'); var HD = require('../hd/hd'); +var Output = require('../primitives/output'); var Account = require('./account'); var MasterKey = require('./masterkey'); var LRU = require('../utils/lru'); @@ -1458,19 +1459,24 @@ Wallet.prototype._fund = co(function* fund(tx, options) { Wallet.prototype.createTX = co(function* createTX(options, force) { var outputs = options.outputs; - var i, tx, total; + var i, tx, output, total; - if (!Array.isArray(outputs) || outputs.length === 0) - throw new Error('No outputs.'); + assert(Array.isArray(output), 'Outputs must be an array.'); + + if (outputs.length === 0) + throw new Error('No outputs available.'); // Create mutable tx tx = new MTX(); // Add the outputs for (i = 0; i < outputs.length; i++) { - tx.addOutput(outputs[i]); - if (tx.outputs[i].isDust(constants.tx.MIN_RELAY)) + output = new Output(outputs[i]); + + if (output.isDust()) throw new Error('Output is dust.'); + + tx.outputs.push(output); } // Fill the inputs with unspents @@ -1479,12 +1485,9 @@ Wallet.prototype.createTX = co(function* createTX(options, force) { // Sort members a la BIP69 tx.sortMembers(); - // Set the locktime to target value or - // `height - whatever` to avoid fee sniping. - // if (options.locktime != null) - // tx.setLocktime(options.locktime); - // else - // tx.avoidFeeSniping(this.db.state.height); + // Set the locktime to target value. + if (options.locktime != null) + tx.setLocktime(options.locktime); if (!tx.isSane()) throw new Error('CheckTransaction failed.');