asserts. consistency.

This commit is contained in:
Christopher Jeffrey 2016-04-19 11:39:55 -07:00
parent 4b2a2371ab
commit 63a9c44762
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
8 changed files with 115 additions and 32 deletions

View File

@ -8,6 +8,7 @@
module.exports = function(bcoin) {
var utils = bcoin.utils;
var assert = utils.assert;
var network = bcoin.protocol.network;
/**
@ -35,7 +36,14 @@ function AbstractBlock(data) {
if (!(this instanceof AbstractBlock))
return new AbstractBlock(data);
this.type = null;
assert(data, 'Block data is required.');
assert(typeof data.version === 'number');
assert(typeof data.prevBlock === 'string');
assert(typeof data.merkleRoot === 'string');
assert(typeof data.ts === 'number');
assert(typeof data.bits === 'number');
assert(typeof data.nonce === 'number');
this.version = data.version;
this.prevBlock = data.prevBlock;
this.merkleRoot = data.merkleRoot;

View File

@ -1501,7 +1501,7 @@ Chain.prototype.add = function add(block, callback, force) {
// fully validated here. They are deserialized,
// validated, and emitted. Hopefully the deserialized
// blocks get cleaned up by the GC quickly.
if (block.type === 'compactblock') {
if (block.compact) {
try {
block = block.toBlock();
} catch (e) {

View File

@ -41,6 +41,8 @@ function Coin(tx, index) {
if (!(this instanceof Coin))
return new Coin(tx, index);
assert(tx, 'Coin data is required.');
if (tx instanceof bcoin.tx) {
this.version = tx.version;
this.height = tx.height;
@ -53,7 +55,6 @@ function Coin(tx, index) {
this.index = index;
} else {
options = tx;
assert(typeof options.script !== 'string');
this.version = options.version;
this.height = options.height;
this.value = options.value;
@ -63,12 +64,13 @@ function Coin(tx, index) {
this.index = options.index;
}
assert(!this.hash || typeof this.hash === 'string');
assert(typeof this.version === 'number');
assert(utils.isFinite(this.height));
assert(bn.isBN(this.value));
assert(this.script instanceof bcoin.script);
assert(typeof this.coinbase === 'boolean');
assert(!this.hash || typeof this.hash === 'string');
assert(!this.index || typeof this.index === 'number');
}
utils.inherits(Coin, bcoin.output);
@ -147,7 +149,7 @@ Coin.prototype.toJSON = function toJSON() {
version: this.version,
height: this.height,
value: utils.btc(this.value),
script: this.script.encode().toString('hex'),
script: this.script.toRaw('hex'),
coinbase: this.coinbase,
hash: this.hash ? utils.revHex(this.hash) : null,
index: this.index
@ -166,7 +168,7 @@ Coin._fromJSON = function _fromJSON(json) {
version: json.version,
height: json.height,
value: utils.satoshi(json.value),
script: bcoin.script.parseScript(new Buffer(json.script, 'hex')),
script: bcoin.script._fromRaw(json.script, 'hex')),
coinbase: json.coinbase,
hash: json.hash ? utils.revHex(json.hash) : null,
index: json.index

View File

@ -54,7 +54,7 @@ function CompactBlock(data) {
bcoin.abstractblock.call(this, data);
this.type = 'compactblock';
this.compact = true;
this.coinbaseHeight = data.coinbaseHeight;
}

View File

@ -35,6 +35,8 @@ function Input(options, mutable) {
if (!(this instanceof Input))
return new Input(options);
assert(options, 'Input data is required.');
this.mutable = !!mutable;
this.prevout = options.prevout;
this.script = bcoin.script(options.script, this.mutable);
@ -44,8 +46,10 @@ function Input(options, mutable) {
if (options.coin)
this.coin = bcoin.coin(options.coin);
assert(typeof this.prevout === 'object');
assert(typeof this.prevout.hash === 'string');
assert(typeof this.prevout.index === 'number');
assert(typeof this.sequence === 'number');
}
Input.prototype.__defineGetter__('type', function() {
@ -260,8 +264,8 @@ Input.prototype.toJSON = function toJSON() {
index: this.prevout.index
},
coin: this.coin ? this.coin.toJSON() : null,
script: this.script.encode().toString('hex'),
witness: bcoin.protocol.framer.witness(this.witness).toString('hex'),
script: this.script.toRaw('hex'),
witness: this.witness.toRaw('hex'),
sequence: this.sequence
};
};
@ -280,8 +284,8 @@ Input._fromJSON = function _fromJSON(json) {
index: json.prevout.index
},
coin: json.coin ? bcoin.coin._fromJSON(json.coin) : null,
script: bcoin.script.parseScript(new Buffer(json.script, 'hex')),
witness: bcoin.protocol.parser.parseWitness(new Buffer(json.witness, 'hex')),
script: bcoin.script._fromRaw(json.script, 'hex'),
witness: bcoin.witness._fromRaw(json.witness, 'hex'),
sequence: json.sequence
};
};

View File

@ -30,6 +30,8 @@ function Output(options, mutable) {
if (!(this instanceof Output))
return new Output(options);
assert(options, 'Output data is required.');
value = options.value;
if (typeof value === 'number') {
@ -139,7 +141,7 @@ Output.prototype.inspect = function inspect() {
Output.prototype.toJSON = function toJSON() {
return {
value: utils.btc(this.value),
script: this.script.encode().toString('hex')
script: this.script.toRaw('hex')
};
};
@ -153,7 +155,7 @@ Output.prototype.toJSON = function toJSON() {
Output._fromJSON = function _fromJSON(json) {
return {
value: utils.satoshi(json.value),
script: bcoin.script.parseScript(new Buffer(json.script, 'hex'))
script: bcoin.script._fromRaw(json.script, 'hex'))
};
};

View File

@ -63,6 +63,8 @@ function Witness(items, mutable) {
this.items = items;
this.redeem = null;
assert(Array.isArray(items));
}
/**
@ -196,6 +198,44 @@ Witness.prototype.indexOf = function indexOf(data) {
return utils.indexOf(this.items, data);
};
/**
* Encode the witness to a Buffer.
* @param {String} enc - Encoding, either `'hex'` or `null`.
* @returns {Buffer|String} Serialized script.
*/
Witness.prototype.toRaw = function toRaw(enc) {
var data = bcoin.protocol.framer.witness(this);
if (enc === 'hex')
data = data.toString('hex');
return data;
};
/**
* Create a witness from a serialized buffer.
* @param {Buffer|String} data - Serialized witness.
* @param {String?} enc - Either `"hex"` or `null`.
* @returns {Object} Naked witness object.
*/
Witness._fromRaw = function _fromRaw(data, enc) {
if (enc === 'hex')
data = new Buffer(data, 'hex');
return bcoin.protocol.parser.parseWitness(data);
};
/**
* Create a Witness from a serialized buffer.
* @param {Buffer|String} data - Serialized witness.
* @param {String?} enc - Either `"hex"` or `null`.
* @returns {Witness}
*/
Witness.fromRaw = function fromRaw(data, enc) {
return new Witness(Witness._fromRaw(data, enc));
};
/**
* Parse a formatted script
* string into a witness object. _Must_
@ -882,6 +922,9 @@ function Script(code, mutable) {
this.raw = null;
this.redeem = null;
assert(Array.isArray(code));
assert(!this.raw || Buffer.isBuffer(this.raw));
}
/**
@ -919,6 +962,19 @@ Script.prototype.encode = function encode() {
return this.raw;
};
/**
* Encode the script to a Buffer. See {@link Script#encode}.
* @param {String} enc - Encoding, either `'hex'` or `null`.
* @returns {Buffer|String} Serialized script.
*/
Script.prototype.toRaw = function toRaw(enc) {
var data = this.encode();
if (enc === 'hex')
data = data.toString('hex');
return data;
};
/**
* Get the script's "subscript" starting at a separator.
* Remove all OP_CODESEPARATORs if present. This bizarre
@ -4005,15 +4061,27 @@ Script.sign = function sign(msg, key, type) {
* representation of a Script object (the same
* properties, but it is not instantiated -- suitable
* as an options object for Script).
* @param {Buffer} buf - Serialized script.
* @param {Buffer|String} data - Serialized script.
* @param {String?} enc - Either `"hex"` or `null`.
* @returns {Object} Naked script object.
*/
Script.parseScript = function parseScript(buf) {
return {
code: Script.decode(buf),
raw: buf
};
Script._fromRaw = function _fromRaw(data, enc) {
if (enc === 'hex')
data = new Buffer(data, 'hex');
return Script.parseScript(data);
};
/**
* Create a script from a serialized buffer.
* @param {Buffer|String} data - Serialized script.
* @param {String?} enc - Either `"hex"` or `null`.
* @returns {Script}
*/
Script.fromRaw = function fromRaw(data, enc) {
return new Script(Script._fromRaw(data, enc));
};
/**

View File

@ -59,15 +59,18 @@ function TX(data, block, index) {
if (!(this instanceof TX))
return new TX(data, block, index);
if (!data)
data = {};
assert(data, 'TX data is required.');
assert(typeof data.version === 'number');
assert(Array.isArray(data.inputs));
assert(Array.isArray(data.outputs));
assert(typeof data.locktime === 'number');
this.type = 'tx';
this.version = data.version != null ? data.version : 1;
this.flag = data.flag || 1;
this.version = data.version;
this.flag = data.flag;
this.inputs = [];
this.outputs = [];
this.locktime = data.locktime || 0;
this.locktime = data.locktime;
this.ts = data.ts || 0;
this.block = data.block || null;
this.index = data.index != null ? data.index : -1;
@ -80,15 +83,11 @@ function TX(data, block, index) {
this._size = data._size || 0;
this._witnessSize = data._witnessSize || 0;
if (data.inputs) {
for (i = 0; i < data.inputs.length; i++)
this.inputs.push(new bcoin.input(data.inputs[i]));
}
for (i = 0; i < data.inputs.length; i++)
this.inputs.push(new bcoin.input(data.inputs[i]));
if (data.outputs) {
for (i = 0; i < data.outputs.length; i++)
this.outputs.push(new bcoin.output(data.outputs[i]));
}
for (i = 0; i < data.outputs.length; i++)
this.outputs.push(new bcoin.output(data.outputs[i]));
if (block && this.ts === 0) {
if (block.type === 'merkleblock') {