more type checking.
This commit is contained in:
parent
bbe8943bf4
commit
f8fadb73a7
@ -73,49 +73,73 @@ function KeyRing(options) {
|
||||
KeyRing.prototype.fromOptions = function fromOptions(options) {
|
||||
var i;
|
||||
|
||||
assert(options.key);
|
||||
|
||||
if (options.network)
|
||||
this.network = bcoin.network.get(options.network);
|
||||
|
||||
if (options.type)
|
||||
if (options.type) {
|
||||
assert(options.type === 'pubkeyhash' || options.type === 'multisig');
|
||||
this.type = options.type;
|
||||
}
|
||||
|
||||
if (options.m)
|
||||
if (options.m != null) {
|
||||
assert(utils.isNumber(options.m));
|
||||
this.m = options.m;
|
||||
}
|
||||
|
||||
if (options.n)
|
||||
if (options.n != null) {
|
||||
assert(utils.isNumber(options.n));
|
||||
this.n = options.n;
|
||||
}
|
||||
|
||||
if (options.witness != null)
|
||||
if (options.witness != null) {
|
||||
assert(typeof options.witness === 'boolean');
|
||||
this.witness = options.witness;
|
||||
}
|
||||
|
||||
if (options.id)
|
||||
if (options.id) {
|
||||
assert(utils.isAlpha(options.id));
|
||||
this.id = options.id;
|
||||
}
|
||||
|
||||
if (options.name)
|
||||
if (options.name) {
|
||||
assert(utils.isAlpha(options.name));
|
||||
this.name = options.name;
|
||||
}
|
||||
|
||||
if (options.account != null)
|
||||
if (options.account != null) {
|
||||
assert(utils.isNumber(options.account));
|
||||
this.account = options.account;
|
||||
}
|
||||
|
||||
if (options.change != null)
|
||||
if (options.change != null) {
|
||||
assert(utils.isNumber(options.change));
|
||||
this.change = options.change;
|
||||
}
|
||||
|
||||
if (options.index != null)
|
||||
if (options.index != null) {
|
||||
assert(utils.isNumber(options.index));
|
||||
this.index = options.index;
|
||||
}
|
||||
|
||||
this.key = options.key;
|
||||
|
||||
if (this.key.getPublicKey)
|
||||
this.key = this.key.getPublicKey();
|
||||
|
||||
assert(Buffer.isBuffer(this.key));
|
||||
|
||||
if (this.n > 1)
|
||||
this.type = 'multisig';
|
||||
|
||||
assert(this.type === 'pubkeyhash' || this.type === 'multisig');
|
||||
|
||||
if (this.m < 1 || this.m > this.n)
|
||||
throw new Error('m ranges between 1 and n');
|
||||
|
||||
this.addKey(this.key);
|
||||
|
||||
if (options.keys) {
|
||||
assert(Array.isArray(options.keys));
|
||||
for (i = 0; i < options.keys.length; i++)
|
||||
this.addKey(options.keys[i]);
|
||||
}
|
||||
@ -139,6 +163,8 @@ KeyRing.fromOptions = function fromOptions(options) {
|
||||
*/
|
||||
|
||||
KeyRing.prototype.addKey = function addKey(key) {
|
||||
assert(Buffer.isBuffer(key));
|
||||
|
||||
if (utils.indexOf(this.keys, key) !== -1)
|
||||
return;
|
||||
|
||||
@ -154,6 +180,8 @@ KeyRing.prototype.addKey = function addKey(key) {
|
||||
*/
|
||||
|
||||
KeyRing.prototype.removeKey = function removeKey(key) {
|
||||
assert(Buffer.isBuffer(key));
|
||||
|
||||
if (this.keys.length === this.n)
|
||||
throw new Error('Cannot remove key.');
|
||||
|
||||
@ -639,12 +667,12 @@ KeyRing.prototype.fromJSON = function fromJSON(json) {
|
||||
|
||||
assert(json);
|
||||
assert(typeof json.network === 'string');
|
||||
assert(typeof json.type === 'string');
|
||||
assert(json.type === 'pubkeyhash' || json.type === 'multisig');
|
||||
assert(utils.isNumber(json.m));
|
||||
assert(utils.isNumber(json.n));
|
||||
assert(typeof json.witness === 'boolean');
|
||||
assert(!json.id || typeof json.id === 'string');
|
||||
assert(!json.name || typeof json.name === 'string');
|
||||
assert(!json.id || utils.isAlpha(json.id));
|
||||
assert(!json.name || utils.isAlpha(json.name));
|
||||
assert(utils.isNumber(json.account));
|
||||
assert(utils.isNumber(json.change));
|
||||
assert(utils.isNumber(json.index));
|
||||
|
||||
@ -2621,3 +2621,17 @@ utils.mkdir = function mkdir(path, dirname) {
|
||||
*/
|
||||
|
||||
utils._paths = {};
|
||||
|
||||
/**
|
||||
* Test whether a string is alphanumeric
|
||||
* enough to use as a leveldb key.
|
||||
* @param {String} key
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
utils.isAlpha = function isAlpha(key) {
|
||||
if (typeof key !== 'string')
|
||||
return false;
|
||||
// We allow /-~ (exclusive), 0-} (inclusive)
|
||||
return /^[\u0030-\u007d]+$/.test(key);
|
||||
};
|
||||
|
||||
@ -83,9 +83,24 @@ Wallet.prototype.fromOptions = function fromOptions(options) {
|
||||
master = MasterKey.fromKey(master);
|
||||
|
||||
this.master = master;
|
||||
this.initialized = options.initialized || false;
|
||||
this.accountDepth = options.accountDepth || 0;
|
||||
this.id = options.id || this.getID();
|
||||
|
||||
if (options.initialized != null) {
|
||||
assert(typeof options.initialized === 'boolean');
|
||||
this.initialized = options.initialized;
|
||||
}
|
||||
|
||||
if (options.accountDepth != null) {
|
||||
assert(utils.isNumber(options.accountDepth));
|
||||
this.accountDepth = options.accountDepth;
|
||||
}
|
||||
|
||||
if (options.id) {
|
||||
assert(utils.isAlpha(options.id), 'Wallet ID must be alphanumeric.');
|
||||
this.id = options.id;
|
||||
}
|
||||
|
||||
if (!this.id)
|
||||
this.id = this.getID();
|
||||
|
||||
return this;
|
||||
};
|
||||
@ -1452,11 +1467,16 @@ Wallet.prototype.toJSON = function toJSON() {
|
||||
*/
|
||||
|
||||
Wallet.prototype.fromJSON = function fromJSON(json) {
|
||||
assert(utils.isAlpha(json.id), 'Wallet ID must be alphanumeric.');
|
||||
assert(typeof json.initialized === 'boolean');
|
||||
assert(utils.isNumber(json.accountDepth));
|
||||
|
||||
this.network = bcoin.network.get(json.network);
|
||||
this.id = json.id;
|
||||
this.initialized = json.initialized;
|
||||
this.accountDepth = json.accountDepth;
|
||||
this.master = MasterKey.fromJSON(json.master);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -1599,45 +1619,59 @@ Account.prototype.fromOptions = function fromOptions(options) {
|
||||
var i;
|
||||
|
||||
assert(options, 'Options are required.');
|
||||
assert(options.id, 'Wallet ID is required.');
|
||||
assert(options.accountKey, 'Account key is required.');
|
||||
assert(utils.isAlpha(options.id), 'Wallet ID must be alphanumeric.');
|
||||
assert(utils.isAlpha(options.name), 'Account name must be alphanumeric.');
|
||||
assert(bcoin.hd.isHD(options.accountKey), 'Account key is required.');
|
||||
assert(utils.isNumber(options.accountIndex), 'Account index is required.');
|
||||
|
||||
this.id = options.id;
|
||||
this.name = options.name;
|
||||
|
||||
if (options.witness != null)
|
||||
if (options.witness != null) {
|
||||
assert(typeof options.witness === 'boolean');
|
||||
this.witness = options.witness;
|
||||
}
|
||||
|
||||
this.accountKey = options.accountKey;
|
||||
|
||||
if (options.accountIndex != null)
|
||||
if (options.accountIndex != null) {
|
||||
assert(utils.isNumber(options.accountIndex));
|
||||
this.accountIndex = options.accountIndex;
|
||||
}
|
||||
|
||||
if (options.receiveDepth != null)
|
||||
if (options.receiveDepth != null) {
|
||||
assert(utils.isNumber(options.receiveDepth));
|
||||
this.receiveDepth = options.receiveDepth;
|
||||
}
|
||||
|
||||
if (options.changeDepth != null)
|
||||
if (options.changeDepth != null) {
|
||||
assert(utils.isNumber(options.changeDepth));
|
||||
this.changeDepth = options.changeDepth;
|
||||
}
|
||||
|
||||
if (options.type)
|
||||
if (options.type) {
|
||||
assert(options.type === 'pubkeyhash' || options.type === 'multisig');
|
||||
this.type = options.type;
|
||||
}
|
||||
|
||||
if (options.m)
|
||||
if (options.m != null) {
|
||||
assert(utils.isNumber(options.m));
|
||||
this.m = options.m;
|
||||
}
|
||||
|
||||
if (options.n)
|
||||
if (options.n != null) {
|
||||
assert(utils.isNumber(options.n));
|
||||
this.n = options.n;
|
||||
}
|
||||
|
||||
if (options.initialized != null)
|
||||
if (options.initialized != null) {
|
||||
assert(typeof options.initialized === 'boolean');
|
||||
this.initialized = options.initialized;
|
||||
}
|
||||
|
||||
if (this.n > 1)
|
||||
this.type = 'multisig';
|
||||
|
||||
assert(this.type === 'pubkeyhash' || this.type === 'multisig',
|
||||
'`type` must be multisig or pubkeyhash.');
|
||||
|
||||
if (this.m < 1 || this.m > this.n)
|
||||
throw new Error('m ranges between 1 and n');
|
||||
|
||||
@ -1647,6 +1681,7 @@ Account.prototype.fromOptions = function fromOptions(options) {
|
||||
this.pushKey(this.accountKey);
|
||||
|
||||
if (options.keys) {
|
||||
assert(Array.isArray(options.keys));
|
||||
for (i = 0; i < options.keys.length; i++)
|
||||
this.pushKey(options.keys[i]);
|
||||
}
|
||||
@ -2258,6 +2293,17 @@ Account.prototype.fromJSON = function fromJSON(json) {
|
||||
var i;
|
||||
|
||||
assert.equal(json.network, this.network.type);
|
||||
assert(utils.isAlpha(json.id), 'Wallet ID must be alphanumeric.');
|
||||
assert(utils.isAlpha(json.name), 'Account name must be alphanumeric.');
|
||||
assert(typeof json.initialized === 'boolean');
|
||||
assert(json.type === 'pubkeyhash' || json.type === 'multisig');
|
||||
assert(utils.isNumber(json.m));
|
||||
assert(utils.isNumber(json.n));
|
||||
assert(typeof json.witness === 'boolean');
|
||||
assert(utils.isNumber(json.accountIndex));
|
||||
assert(utils.isNumber(json.receiveDepth));
|
||||
assert(utils.isNumber(json.changeDepth));
|
||||
assert(Array.isArray(json.keys));
|
||||
|
||||
this.id = json.id;
|
||||
this.name = json.name;
|
||||
@ -2405,10 +2451,27 @@ function MasterKey(options) {
|
||||
*/
|
||||
|
||||
MasterKey.prototype.fromOptions = function fromOptions(options) {
|
||||
this.encrypted = !!options.encrypted;
|
||||
this.iv = options.iv;
|
||||
this.ciphertext = options.ciphertext;
|
||||
this.key = options.key || null;
|
||||
assert(options);
|
||||
|
||||
if (options.encrypted != null) {
|
||||
assert(typeof options.encrypted === 'boolean');
|
||||
this.encrypted = options.encrypted;
|
||||
}
|
||||
|
||||
if (options.iv) {
|
||||
assert(Buffer.isBuffer(options.iv));
|
||||
this.iv = options.iv;
|
||||
}
|
||||
|
||||
if (options.ciphertext) {
|
||||
assert(Buffer.isBuffer(options.ciphertext));
|
||||
this.ciphertext = options.ciphertext;
|
||||
}
|
||||
|
||||
if (options.key) {
|
||||
assert(Buffer.isBuffer(options.key));
|
||||
this.key = options.key;
|
||||
}
|
||||
|
||||
assert(this.encrypted ? !this.key : this.key);
|
||||
|
||||
|
||||
@ -468,7 +468,7 @@ WalletDB.prototype.get = function get(id, callback) {
|
||||
*/
|
||||
|
||||
WalletDB.prototype.save = function save(wallet, callback) {
|
||||
if (!isAlpha(wallet.id))
|
||||
if (!utils.isAlpha(wallet.id))
|
||||
return callback(new Error('Wallet IDs must be alphanumeric.'));
|
||||
|
||||
this.db.put('w/' + wallet.id, wallet.toRaw(), callback);
|
||||
@ -664,7 +664,7 @@ WalletDB.prototype.getAccountIndex = function getAccountIndex(id, name, callback
|
||||
WalletDB.prototype.saveAccount = function saveAccount(account, callback) {
|
||||
var index, batch;
|
||||
|
||||
if (!isAlpha(account.name))
|
||||
if (!utils.isAlpha(account.name))
|
||||
return callback(new Error('Account names must be alphanumeric.'));
|
||||
|
||||
batch = this.db.batch();
|
||||
@ -1464,11 +1464,6 @@ function serializePaths(out) {
|
||||
return p.render();
|
||||
}
|
||||
|
||||
function isAlpha(key) {
|
||||
// We allow /-~ (exclusive), 0-} (inclusive)
|
||||
return /^[\u0030-\u007d]+$/.test(key);
|
||||
}
|
||||
|
||||
function ReadLock(parent) {
|
||||
if (!(this instanceof ReadLock))
|
||||
return new ReadLock(parent);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user